Tento článok je zrkadlovým článkom o strojovom preklade, kliknite sem pre prechod na pôvodný článok.

Pohľad: 15343|Odpoveď: 2

[Komunikácia] [Preklad]. NET na použitie rozdielu medzi ValueTask a Task

[Kopírovať odkaz]
Zverejnené 17. marca 2022 o 11:21:50 | | | |


Používanie tried Task alebo Task má výkonnostné úzke miesto, o ktorom sme v predchádzajúcich článkoch nehovorili. Stručne povedané, tieto triedy vedú, keď sú výsledky okamžite dostupnéZbytočné prideľovanie。 To znamená, že nová úloha alebo objekt úlohy sa vždy vytvorí, aj keď je výsledok už dostupný. Spomenuli sme, že koncept async/await, ktorý sme použili v predchádzajúcich článkoch, existuje už od vydania .NET 4.5. Táto funkcia bola od C# 7 vylepšená verziou .NET 4.7 so štruktúrou ValueTask, ktorá môže slúžiť ako návrat pre asynchrónne funkcie.

Štruktúra ValueTask


Štruktúra ValueTask sa prvýkrát objavila v repozitári corefxlab v roku 2015. Tento repozitár sa používa na experimentovanie a skúmanie nových nápadov, ktoré sa môžu, ale nemusia dostať do hlavného repozitára corefx. Corefx repozitár je repozitár, kde sa nachádzajú všetky základné knižnice .NET Core. Vyvinul ju a navrhol Stephen Taub pre knižnicu System.Threading.Tasks.Channels. V tom čase Stephen stručne vysvetlil:

Adresa knižnice corefxlab:Prihlásenie na hypertextový odkaz je viditeľné.


ValueTask je samostatné zjednotenie T a úlohy, ktoré umožňuje ReadAsync voľne alokovať na synchronné vrátenie dostupných hodnôt T (na rozdiel od použitia Task.FromResult, ktorý vyžaduje alokáciu inštancie úlohy). ValueTask je čakateľný, takže spotreba väčšiny inštancií je nerozlíšiteľná od spotreby úloh.
Mnoho ľudí vidí výhody používania tejto štruktúry, ktorá je zahrnutá v C# 7 ako súčasť balíka System.Threading.Tasks.Extensions NuGet. Takže, skôr než sa pustíme do štruktúry ValueTask, pozrime sa na problém, ktorý používa na riešenie. Keďže Task(Task) je typ referencie, začnite sAsynchrónna metóda, ktorá vracia objekt úlohy, znamená, že je alokovaný na halde zakaždým。 To je v mnohých prípadoch nevyhnutné.

Avšak v niektorých prípadoch asynchrónne metódy vracajú výsledky okamžite alebo sú synchronizované. V týchto prípadoch je táto alokácia zbytočná a môže byť nákladná v častiach kódu kritických pre výkon. Až do vydania .NET 4.7 sa tomu nedalo vyhnúť, pretože asynchrónne metódy museli vracať Task, Task <T>alebo void (posledné bolo zvyčajne nežiaduce). V tejto verzii .NET je to rozšírené, čo znamená, že asynchrónna metóda môže vrátiť akýkoľvek typ, pokiaľ má prístupnú metódu GetAwaiter. ValueTask je konkrétnym príkladom tohto typu a bol tiež pridaný do tohto vydania.

Môžete si prezrieť repozitár corefx a vidieť kompletnú implementáciu ValueTask, tu je sekcia API, o ktorú máme záujem:



Ako štruktúra umožňuje ValueTask písať asynchrónne metódy, ktoré počas synchronného behu nealokujú pamäť. Konzistentnosť API konceptu async/await nie je týmto spôsobom narušená. Okrem toho táto stavba čaká samostatne, čo ju robí jednoduchou na používanie. Napríklad, ak spustíme tento jednoduchý kód:

V metóde MultiplyAsync simulujeme situáciu, kde sa chceme vyhnúť používaniu úlohy a vrátiť len jednoduché celé číslo. Toto sa robí v príkaze if metódy, kde v podstate kontrolujeme, či je odovzdaný parameter nula. Problém jeAj keď je naša podmienka v príkaze if pravdivá, kód vyššie vytvorený vytvorí objekt úlohy。 Tento problém riešime takto:

ValueTask a Task



Ako už bolo spomenuté, používanie ValueTask prináša dve hlavné výhody:

  • Zlepšenia výkonu
  • Zvýšiť flexibilitu implementácie


Aké sú teda čísla za zlepšeniami výkonu? Pozorujte tento kód:


Ak spustíme tento kód, trvá 120 ns na vykonanie JIT. Ak nahradíme Úlohu HodnotouÚlohou takto:

S JIT dosiahneme čas vykonania 65 ns. Je pravda, že kvôli oneskoreniu Task.Delay nevykonávame synchronne, ale vidíme zlepšenie času vykonávania.

Ďalšou výhodou, ktorú sme spomenuli, je zvýšená flexibilita implementácie. Čo to vlastne znamená? Implementácie asynchrónnych rozhraní, ktoré by mali byť synchronizované, budú nútené používať Task.Run alebo Task.FromResult. Samozrejme, to vedie k problémom s výkonom, o ktorých sme hovorili skôr. Keď používame ValueTask, je pravdepodobnejšie, že si vyberieme medzi synchronnými alebo asynchrónnymi implementáciami. Majte na pamäti, že to môže byť znak, že váš kód nemusí byť dobre navrhnutý, ak sa vám to stane.

Napríklad pozorujte toto rozhranie:


Povedzme, že ho chcete volať z kódu takto:

Keďže v rozhraní používame ValueTask, implementácia rozhrania môže byť synchronná alebo asynchrónna. Túto výhodu môžeme získať tak, že v podstate preskočime pridanie niektorých funkcií do IThingu, ktoré riešia synchronizačné správanie. Takto je oveľa jednoduchšie používať toto rozhranie. Tu je synchronná implementácia vyššie uvedeného rozhrania:

Tu je asynchrónna implementácia toho istého rozhrania:

Avšak pred použitím ValueTask musíme zvážiť určité kompromisy. Je ľahké si myslieť, že ValueTask by sa mal používať predvolene namiesto Task, čo určite nie je pravda. Napríklad, hoci nám ValueTask pomáha vyhnúť sa zbytočným priradeniam, keď je k dispozícii synchronizácia výsledkov, obsahuje aj dve polia.

Je dôležité si uvedomiť, že toto je štruktúra, ktorú tu používame, čo znamená, že používame typy hodnôt a všetky ich bremená. Úloha je naopak referenčný typ s iba jedným poľom.Keď používate ValueTask, máme viac dát na spracovanie a spracovanie. Ak sa takáto metóda čaká v asynchrónnej metóde, potom asynchrónna metóda jeStavový automat bude tiež väčší, pretože uloženie celej štruktúry zvyčajne vyžaduje viac miesta než ukladanie jednej referencie.

Preto ľudia v Microsofte skutočne odporúčajú používať Úlohy alebo Úlohy ako predvolený typ návratu pre asynchrónne metódy. Až po analýze výkonu by ste mali zvážiť prechod na ValueTask.


súhrn

ValueTask je štruktúra zavedená v .NET 4.7, ktorá nám poskytuje množstvo možností na použitie asynchrónnych metód v .NET. Nie je to však bez ceny. To je užitočné pre výkonnostne kritické metódy, ktoré sa vykonávajú synchronne. S nimi sa môžeme vyhnúť priraďovaniu zbytočných objektov. Napriek tomu ako hodnotový typ prináša všetky problémy, ktoré hodnotové typy zvyčajne majú. Preto môžeme z tejto štruktúry profitovať, ale musíme byť opatrní.

Pôvodná adresa:Prihlásenie na hypertextový odkaz je viditeľné.




Predchádzajúci:【Practical Action】Use Docker to build an IPsec VPN server
Budúci:Použite OpenConnect namiesto Cisco AnyConnect, aby ste sa vyhli zámkom smerovacej tabuľky
Zverejnené 18. marca 2022 22:21:57 |
Príď sa znova učiť.
Zverejnené 22. 3. 2022 o 14:05:53 |
Naučte sa podstatu učeniaUjde to
Vyhlásenie:
Všetok softvér, programovacie materiály alebo články publikované spoločnosťou Code Farmer Network slúžia len na vzdelávacie a výskumné účely; Vyššie uvedený obsah nesmie byť použitý na komerčné alebo nezákonné účely, inak nesú všetky následky používateľmi. Informácie na tejto stránke pochádzajú z internetu a spory o autorské práva s touto stránkou nesúvisia. Musíte úplne vymazať vyššie uvedený obsah zo svojho počítača do 24 hodín od stiahnutia. Ak sa vám program páči, podporte originálny softvér, zakúpte si registráciu a získajte lepšie originálne služby. Ak dôjde k akémukoľvek porušeniu, kontaktujte nás prosím e-mailom.

Mail To:help@itsvse.com