Ta članek je zrcalni članek strojnega prevajanja, kliknite tukaj za skok na izvirni članek.

Pogled: 15343|Odgovoriti: 2

[Komunikacija] [Prevod]. NET za uporabo razlike med ValueTask in Task

[Kopiraj povezavo]
Objavljeno 17. 3. 2022 ob 11:21:50 | | | |


Uporaba razredov Task ali Task ima ozko grlo v zmogljivosti, ki ga nismo omenili v prejšnjih člankih. Na kratko, ti tečaji vodijo, ko so rezultati takoj na voljoNepotrebna razporeditev。 To pomeni, da bo vedno ustvarjena nova naloga ali objekt naloge, tudi če je rezultat že na voljo. Omenili smo, da je koncept async/await, ki smo ga uporabljali v prejšnjih člankih, prisoten že od izdaje .NET 4.5. Ta funkcija je bila izboljšana od C# 7 z različico .NET 4.7 z ValueTask strukturo, ki se lahko uporablja kot vračilo za asinhrone funkcije.

Struktura ValueTaska


Struktura ValueTask se je prvič pojavila v repozitoriju corefxlab leta 2015. Ta repozitorij se uporablja za eksperimentiranje in raziskovanje novih idej, ki morda ne pridejo v glavni corefx repozitorij. Corefx repozitorij je repozitorij, kjer se nahajajo vse osnovne .NET Core knjižnice. Razvil in predlagal ga je Stephen Taub za knjižnico System.Threading.Tasks.Channels. Takrat je Stephen podal kratko razlago:

Naslov knjižnice corefxlab:Prijava do hiperpovezave je vidna.


ValueTask je ločena združitev T in Task, ki omogoča ReadAsyncu prosto dodeljevanje za sinhrono vračanje razpoložljivih T vrednosti (za razliko od uporabe Task.FromResult, ki zahteva dodelitev instance Task). ValueTask je mogoče počakati, zato je poraba večine instanc nerazločljiva od porabe nalog.
Veliko ljudi vidi prednosti uporabe te strukture, ki je vključena v C# 7 kot del paketa System.Threading.Tasks.Extensions NuGet. Preden se poglobimo v strukturo ValueTask, si poglejmo problem, ki ga uporablja za reševanje. Ker je Task(Task) referenčni tip, začni zAsinhrona metoda, ki vrača objekt Task, pomeni, da je ta vsakič dodeljen na kupu。 To je v mnogih primerih nujno.

Vendar pa v nekaterih primerih asinhrone metode takoj ali sinhrono vrnejo rezultate. V takih primerih ta dodelitev ni potrebna in lahko postane draga v delih kode, ki so kritični za zmogljivost. Do izdaje .NET 4.7 tega ni bilo mogoče preprečiti, saj so asinhrone metode morale vrniti Nalogo, Nalogo <T>ali razveljavitev (zadnja možnost je bila običajno nezaželena). V tej različici .NET je to razširjeno, kar pomeni, da lahko asinhrona metoda vrne katerikoli tip, dokler ima dostopno metodo GetAwaiter. ValueTask je konkreten primer te vrste in je bil prav tako dodan tej izdaji.

Lahko brskate po repozitoriju corefx in si ogledate celotno implementacijo ValueTask, tukaj je API razdelek, ki nas zanima:



Kot struktura ValueTask omogoča pisanje asinhronih metod, ki med sinhronim izvajanjem ne dodeljujejo pomnilnika. Skladnost API koncepta async/await ni na ta način ogrožena. Poleg tega ta struktura čaka samostojno, kar jo naredi enostavno za uporabo. Na primer, če zaženemo to preprosto kodo:

V metodi MultiplyAsync simuliramo situacijo, ko želimo preprečiti uporabo naloge in vrniti le preprosto celo število. To se izvede v stavku if metode, kjer v bistvu preverjamo, ali je preneseni parameter enak nič. Težava jeTudi če je naš pogoj v stavku if resničen, zgornja koda ustvari objekt Task。 Ta problem rešimo takole:

ValueTask in Naloga



Kot je bilo že omenjeno, obstajata dve glavni prednosti uporabe ValueTask:

  • Izboljšave zmogljivosti
  • Povečajte prilagodljivost implementacije


Torej, kakšne so številke za izboljšave zmogljivosti? Opazujte to kodo:


Če zaženemo to kodo, traja 120 ns za izvedbo JIT-a. Če Nalogo zamenjamo z ValueTask takole:

Z JIT bomo dosegli čas izvedbe 65ns. Res je, da zaradi Task.Delay ne izvajamo sinhrono, vendar opažamo izboljšanje časa izvajanja.

Druga prednost, ki smo jo omenili, je večja prilagodljivost pri izvajanju. Kaj točno to pomeni? No, implementacije asinhronih vmesnikov, ki bi morale biti sinhronizirane, bodo prisiljene uporabljati Task.Run ali Task.FromResult. Seveda to vodi do težav z zmogljivostjo, o katerih smo govorili prej. Ko uporabljamo ValueTask, bomo bolj verjetno izbirali med sinhronimi ali asinhronimi implementacijami. Upoštevajte, da je to lahko znak, da vaša koda morda ni dobro zasnovana, če se vam to zgodi.

Na primer, opazujte ta vmesnik:


Recimo, da želite klicati iz kode takole:

Ker v vmesniku uporabljamo ValueTask, je implementacija vmesnika lahko sinhrona ali asinhrona. To prednost lahko dosežemo tako, da v IThing preprosto preskočimo dodajanje nekaterih funkcij, ki upravljajo sinhronizacijo. Ta vmesnik je veliko lažje uporabljati na ta način. Tukaj je sinhrona implementacija zgornjega vmesnika:

Tukaj je asinhrona implementacija istega vmesnika:

Vendar pa moramo pred uporabo ValueTask upoštevati nekatere kompromise. Lahko je misliti, da bi morali privzeto uporabljati ValueTask namesto Task, kar zagotovo ni res. Na primer, čeprav nam ValueTask pomaga preprečiti nepotrebne dodelitve, kadar je na voljo sinhronizacija rezultatov, vsebuje tudi dve polji.

Pomembno je vedeti, da uporabljamo to strukturo, kar pomeni, da uporabljamo vrste vrednosti in vse njihove bremena. Naloga pa je referenčni tip z le enim poljem.Ko uporabljate ValueTask, imamo več podatkov za obdelavo in obdelavo. Če se na takšno metodo čaka v asinhroni metodi, potem je asinhrona metodaTudi državni stroj bo večji, ker shranjevanje celotne strukture običajno zahteva več prostora kot shranjevanje ene same reference.

Zato ljudje pri Microsoftu dejansko priporočajo uporabo Naloge ali Naloge kot privzete vrste vrnitve za asinhrone metode. Šele po analizi zmogljivosti razmislite o prehodu na ValueTask.


Povzetek

ValueTask je struktura, uvedena v .NET 4.7, ki nam ponuja veliko možnosti za uporabo asinhronih metod v .NET. Vendar pa to ni brez cene. To je uporabno za metode, kritične za zmogljivost, ki se izvajajo sinhrono. Z njimi se lahko izognemo dodeljevanju nepotrebnih predmetov. Kljub temu pa kot vrednostni tip prinaša vse težave, ki jih vrednostni tipi običajno imajo. Zato lahko od te strukture imamo koristi, vendar moramo biti previdni.

Izvirni naslov:Prijava do hiperpovezave je vidna.




Prejšnji:【Practical Action】Use Docker to build an IPsec VPN server
Naslednji:Preklopite na OpenConnect namesto Cisco AnyConnect, da se izognete zaklepanju usmerjevalne tabele
Objavljeno 18. 3. 2022 ob 22:21:57 |
Pridi se spet učiti.
Objavljeno 22. 3. 2022 ob 14:05:53 |
Spoznajte bistvo učenjaNi slabo
Disclaimer:
Vsa programska oprema, programski materiali ali članki, ki jih izdaja Code Farmer Network, so namenjeni zgolj učnim in raziskovalnim namenom; Zgornja vsebina ne sme biti uporabljena v komercialne ali nezakonite namene, sicer uporabniki nosijo vse posledice. Informacije na tej strani prihajajo z interneta, spori glede avtorskih pravic pa nimajo nobene zveze s to stranjo. Zgornjo vsebino morate popolnoma izbrisati z računalnika v 24 urah po prenosu. Če vam je program všeč, podprite pristno programsko opremo, kupite registracijo in pridobite boljše pristne storitve. Če pride do kakršne koli kršitve, nas prosimo kontaktirajte po elektronski pošti.

Mail To:help@itsvse.com