Introducere:
Programarea asincronă a devenit o tendință populară în dezvoltarea software-ului modern. Două tehnici utilizate în mod obișnuit pentru programarea asincronă în C# sunt Sarcini și Fire . Cu toate acestea, mulți dezvoltatori sunt confuzi cu privire la diferențele dintre Sarcini și Fire și când să folosiți fiecare dintre ele. În acest articol, vom vedea diferențele prezente între Sarcini și Fire în C# și oferiți instrucțiuni pentru când să utilizați fiecare dintre ele.
Ce sunt sarcinile?
În C#, o sarcină este o abstractizare de nivel superior pentru rularea codului asincron. O sarcină denotă o unitate de lucru care trebuie executată asincron și poate returna sau nu o valoare. O sarcină este de obicei creată cu ajutorul Clasa Task Factory , care oferă mai multe metode pentru crearea și executarea sarcinilor.
Sarcinile folosesc a Bazin de fire pentru a-și executa munca, ceea ce înseamnă că Sarcinile sunt executate pe unul dintre Thread-urile din Bazin de fire. Când o sarcină este creată, aceasta este adăugată la Coada pool-ului de fire , iar unul dintre firele din pool este folosit pentru a executa Sarcina. Odată ce sarcina este finalizată, Thread-ul revine în pool, gata să fie folosit pentru o altă sarcină.
Sarcinile au mai multe avantaje față de Threads:
- Sarcinile sunt mai ușoare decât Threads. Sarcinile folosesc mai puține resurse de sistem, cum ar fi memoria și timpul CPU, în comparație cu Threads.
- Sarcinile sunt mai ușor de gestionat decât Threads. Sarcinile oferă o abstractizare de nivel superior pentru programarea asincronă, ceea ce facilitează scrierea și întreținerea codului.
- Sarcinile pot oferi, de asemenea, performanțe mai bune decât Threads în anumite situații. Acest lucru se datorează faptului că Tasks utilizează a Bazin de fire , care poate gestiona Thread-urile mai eficient decât crearea și distrugerea Thread-urilor pentru fiecare unitate de lucru.
Ce sunt Threads-urile?
În C#, un Thread este o abstractizare de nivel inferior pentru rularea codului asincron. Un Thread reprezintă un construct la nivel de sistem de operare care este utilizat pentru a executa codul asincron. Un Thread poate returna sau nu o valoare și este de obicei creat cu ajutorul Clasa de fire .
Threadurile își folosesc propriile resurse, cum ar fi memoria și timpul procesorului, și sunt de obicei create și distruse explicit de către dezvoltator. Când este creat un Thread, acesta începe să se execute imediat și continuă să se execute până când este oprit în mod explicit sau își finalizează activitatea.
Threadurile au mai multe dezavantaje în comparație cu Sarcini:
- Firele sunt mai grele decât Tasks. Threadurile folosesc mai multe resurse de sistem, cum ar fi memoria și timpul CPU, în comparație cu Sarcini.
- Threadurile sunt mai greu de gestionat decât Sarcinile. Threadurile necesită mai multă programare și sincronizare la nivel scăzut, ceea ce face mai dificilă scrierea și întreținerea codului.
- Threadurile pot oferi, de asemenea, performanțe mai slabe decât Tasks în anumite situații. Acest lucru se datorează faptului că crearea și distrugerea Thread-urilor pentru fiecare unitate de lucru poate fi ineficientă, mai ales când există multe unități de lucru de executat.
Când să utilizați sarcinile:
Sarcinile sunt recomandate atunci când doriți să efectuați o unitate de lucru în mod asincron și nu aveți nevoie de un control fin asupra execuției. Sarcinile sunt perfecte pentru a executa unități de lucru mici și de scurtă durată, cum ar fi operațiuni I/O sau calcule simple.
Sarcinile sunt, de asemenea, recomandate atunci când doriți să profitați de beneficiile unui Bazin de fire . A Bazin de fire poate gestiona Thread-urile mai eficient decât crearea și distrugerea Thread-urilor pentru fiecare unitate de lucru. Acest lucru poate duce la o performanță mai bună, mai ales atunci când există multe unități de lucru de executat.
Sarcinile sunt utile și atunci când doriți să înlănțuiți operațiuni asincrone. Sarcinile pot fi combinate folosind operatorul await pentru a crea un lanț de operații asincrone care se execută una după alta. Acest lucru poate fi important atunci când doriți să efectuați o serie de operații asincrone dependente.
Când să folosiți firele:
Thread-urile în C# ar trebui să fie folosite atunci când aveți nevoie de un control fin asupra execuției și când aveți cerințe specifice care nu pot fi îndeplinite cu abstracțiile de nivel superior oferite de Tasks. Iată câteva situații în care Threads poate fi alegerea mai bună:
Unități de lucru cu durată lungă de viață:
Threadurile sunt mai potrivite pentru unitățile de lucru cu durată lungă de viață, cum ar fi serviciile de fundal sau calculele complexe care necesită mai mult control asupra execuției. În astfel de cazuri, este adesea necesar să se controleze execuția codului într-un mod mai precis decât ceea ce oferă Tasks.
Control fin asupra execuției firului:
Firele vă permit să setați Priorități de fire, Sincronizare de fire , și Firul se anulează . Dacă trebuie să personalizați modul în care este executat codul, Threads oferă o interfață de nivel scăzut care vă permite să faceți acest lucru.
Programare la nivel scăzut:
interfață vs clasă abstractă
Threadurile necesită mai multă programare și sincronizare la nivel scăzut, ceea ce poate fi util dacă aveți cerințe specializate care nu pot fi îndeplinite cu abstracțiile de nivel superior oferite de Tasks.
Interoperabilitate cu cod negestionat:
Dacă trebuie să interoperați cu cod negestionat, Threads poate fi singura opțiune. În astfel de cazuri, poate fi necesar să creați și să controlați manual Threads pentru a vă asigura că codul dvs. funcționează corect cu codul negestionat.
Considerații de performanță:
În unele situații, crearea și distrugerea Thread-urilor pentru fiecare unitate de lucru poate fi ineficientă, mai ales când există multe unități de lucru de executat. În astfel de cazuri, utilizarea Threads poate fi o opțiune mai bună, deoarece pot fi reutilizate pentru mai multe unități de lucru.