MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Introducere în multithreading - Clasa Thread

Unul dintre aspectele cheie în programarea modernă este multithreading-ul. Conceptul principal în lucrul cu multithreading-ul este thread-ul. Un thread reprezintă o parte din codul programului. La rularea programului, fiecărui thread i se alocă un anumit cuantum de timp.

Prin intermediul multithreading-ului, putem aloca în aplicație mai multe thread-uri care vor executa diverse sarcini simultan. Dacă avem, de exemplu, o aplicație grafică ce trimite o cerere către un server sau citește și procesează un fișier mare, fără multithreading, interfața grafică ar fi blocată pe durata executării sarcinii.

Datorită thread-urilor, putem aloca trimiterea cererii sau orice altă sarcină care necesită timp îndelungat unui thread separat. Astfel, de exemplu, aplicațiile client-server (și nu doar ele) sunt de neconceput fără multithreading.

Funcționalitatea principală pentru utilizarea thread-urilor într-o aplicație este concentrată în namespace-ul System.Threading. În acesta este definită clasa ce reprezintă un thread separat - clasa Thread.

Clasa Thread definește o serie de metode și proprietăți care permit gestionarea thread-ului și obținerea informațiilor despre acesta. Proprietățile principale ale clasei sunt:

  • ExecutionContext: permite obținerea contextului în care se execută thread-ul
  • IsAlive: indică dacă thread-ul rulează în prezent
  • IsBackground: indică dacă thread-ul este de fundal
  • Name: conține numele thread-ului
  • ManagedThreadId: returnează identificatorul numeric al thread-ului curent
  • Priority: stochează prioritatea thread-ului - valoarea unei enumerații ThreadPriority: Lowest BelowNormal Normal AboveNormal Highest

Implicit, unui thread i se atribuie valoarea Normal. Totuși, putem modifica prioritatea în timpul rulării programului. De exemplu, putem crește importanța thread-ului setând prioritatea Highest. Mediul CLR va citi și analiza valorile priorității și, pe baza acestora, va aloca thread-ului respectiv o anumită cantitate de timp.

  • ThreadState returnează starea thread-ului - una dintre valorile enumerației ThreadState:
  • Aborted: thread-ul este oprit, dar încă nu a fost finalizat
  • AbortRequested: pentru thread a fost apelată metoda Abort, dar oprirea încă nu a avut loc
  • Background: thread-ul rulează în mod de fundal
  • Running: thread-ul este pornit și rulează (nu este suspendat)
  • Stopped: thread-ul este finalizat
  • StopRequested: thread-ul a primit o cerere de oprire
  • Suspended: thread-ul este suspendat
  • SuspendRequested: thread-ul a primit o cerere de suspendare
  • Unstarted: thread-ul nu a fost încă pornit
  • WaitSleepJoin: thread-ul este blocat în urma apelării metodelor Sleep sau Join

În timpul rulării thread-ului, starea acestuia poate fi modificată de mai multe ori prin intermediul metodelor. De exemplu, la început, înainte de aplicarea metodei Start, starea este Unstarted. După pornirea thread-ului, starea se schimbă în Running. Apelând metoda Sleep, starea se va schimba în WaitSleepJoin.

În plus, proprietatea statică CurrentThread a clasei Thread permite obținerea thread-ului curent.

Într-un program C#, există cel puțin un thread - thread-ul principal, în care se execută metoda Main.

De exemplu, utilizăm proprietățile descrise mai sus pentru a obține informații despre thread:

using System.Threading;

// obținem thread-ul curent
Thread currentThread = Thread.CurrentThread;

// obținem numele thread-ului
Console.WriteLine($"Numele thread-ului: {currentThread.Name}");
currentThread.Name = "Metoda Main";
Console.WriteLine($"Numele thread-ului: {currentThread.Name}");

Console.WriteLine($"Thread-ul este pornit: {currentThread.IsAlive}");
Console.WriteLine($"Id-ul thread-ului: {currentThread.ManagedThreadId}");
Console.WriteLine($"Prioritatea thread-ului: {currentThread.Priority}");
Console.WriteLine($"Starea thread-ului: {currentThread.ThreadState}");

În acest caz, vom obține aproximativ următorul output:

Numele thread-ului:
Numele thread-ului: Metoda Main
Thread-ul este pornit: True
Id-ul thread-ului: 1
Prioritatea thread-ului: Normal
Starea thread-ului: Running

Deoarece implicit, proprietatea Name a obiectelor Thread nu este setată, în primul caz vom obține o valoare de șir gol pentru această proprietate.

De asemenea, clasa Thread definește o serie de metode pentru gestionarea thread-urilor. Principalele dintre acestea sunt:

  • Metoda statică GetDomain returnează o referință la domeniul aplicației
  • Metoda statică GetDomainID returnează id-ul domeniului aplicației în care se execută thread-ul curent
  • Metoda statică Sleep oprește thread-ul pentru un anumit număr de milisecunde
  • Metoda Interrupt întrerupe thread-ul aflat în starea WaitSleepJoin
  • Metoda Join blochează execuția thread-ului care a apelat această metodă până când se finalizează thread-ul pentru care a fost apelată metoda
  • Metoda Start pornește thread-ul

De exemplu, utilizăm metoda Sleep pentru a seta o întârziere în execuția aplicației:

using System.Threading;

for(int i = 0; i < 10; i++)
{
   Thread.Sleep(500);      // întârziere în execuție de 500 de milisecunde
   Console.WriteLine(i);
}
← Lecția anterioară Lecția următoare →