Šis straipsnis yra veidrodinis mašininio vertimo straipsnis, spauskite čia norėdami pereiti prie originalaus straipsnio.

Rodinys: 15343|Atsakyti: 2

[Komunikatas] [Vertimas]. NET, kad būtų naudojamas skirtumas tarp ValueTask ir Task

[Kopijuoti nuorodą]
Publikuota 2022-3-17 11:21:50 | | | |


Naudojant užduočių ar užduočių klases yra našumo kliūtis, kurios nepaminėjome ankstesniuose straipsniuose. Trumpai tariant, šios klasės pirmauja, kai rezultatai yra iš karto prieinamiNereikalingas paskirstymas。 Tai reiškia, kad nauja užduotis arba užduoties objektas visada bus sukurtas, net jei rezultatas jau pasiekiamas. Dabar minėjome, kad asinchroninė / laukimo koncepcija, kurią naudojome ankstesniuose straipsniuose, egzistuoja nuo .NET 4.5 išleidimo. Ši funkcija buvo patobulinta nuo C# 7 su .NET 4.7 versija su ValueTask struktūra, kuri gali būti naudojama kaip asinchroninių funkcijų grąžinimas.

ValueTask struktūra


"ValueTask" struktūra pirmą kartą pasirodė "corefxlab" saugykloje 2015 m. Ši saugykla naudojama eksperimentuoti ir tyrinėti naujas idėjas, kurios gali patekti į pagrindinę corefx saugyklą. "Corefx" saugykla yra saugykla, kurioje yra visos .NET Core bazinės bibliotekos. Jį sukūrė ir pasiūlė Stephenas Taubas System.Threading.Tasks.Channels bibliotekai. Tuo metu Stephenas pateikė trumpą paaiškinimą:

CorefxLab bibliotekos adresas:Hipersaito prisijungimas matomas.


ValueTask yra atskira T ir Task sąjunga, leidžianti ReadAsync laisvai paskirstyti, kad sinchroniškai grąžintų turimas T reikšmes (skirtingai nei naudojant Task.FromResult, kuriam reikia paskirstyti užduoties egzempliorių). ValueTask galima laukti, todėl daugumos egzempliorių suvartojimas nesiskiria nuo užduočių suvartojimo.
Daugelis žmonių mato šios struktūros, kuri yra įtraukta į C# 7 kaip System.Threading.Tasks.Extensions NuGet paketo dalį, naudojimo pranašumus. Taigi, prieš pasinerdami į "ValueTask" struktūrą, panagrinėkime problemą, kurią ji naudoja sprendžiant. Kadangi Task(Task) yra nuorodos tipas, pradėkite nuoAsinchroninis metodas, grąžinantis užduoties objektą, reiškia, kad jis kiekvieną kartą paskirstomas krūvoje。 Tai būtina daugeliu atvejų.

Tačiau kai kuriais atvejais asinchroniniai metodai pateikia rezultatus iš karto arba užbaigia sinchroniškai. Tokiais atvejais šis paskirstymas yra nereikalingas ir gali tapti brangus našumui svarbiose kodo dalyse. Iki .NET 4.7 leidimo nebuvo galimybės to išvengti, nes asinchroniniai metodai turėjo grąžinti užduotį, užduotį <T>arba anuliuoti (paskutinis paprastai buvo nepageidautinas). Šioje .NET versijoje tai išplėsta, o tai reiškia, kad asinchroninis metodas gali grąžinti bet kokį tipą, jei jis turi prieinamą GetAwaiter metodą. "ValueTask" yra konkretus tokio tipo pavyzdys, kuris taip pat buvo įtrauktas į šį leidimą.

Galite naršyti corefx saugyklą ir pamatyti visą ValueTask įgyvendinimą, čia yra mus dominantis API skyrius:



Kaip struktūra, "ValueTask" leidžia rašyti asinchroninius metodus, kurie sinchroninio vykdymo metu nepaskirsto atminties. Tokiu būdu nepažeidžiamas asinchroninės / laukimo koncepcijos API nuoseklumas. Be to, ši konstrukcija laukia savaime, todėl ją lengva naudoti. Pavyzdžiui, jei paleidžiame šį paprastą kodą:

Taikydami MultiplyAsync metodą, imituojame situaciją, kai norime išvengti užduoties naudojimo ir grąžinti tik paprastą sveikąjį skaičių. Tai daroma metodo if sakinyje, kur iš esmės tikriname, ar perduotas parametras yra lygus nuliui. Problema yra ta, kadNet jei mūsų sąlyga sakinyje if yra teisinga, aukščiau pateiktas kodas sukuria užduoties objektą。 Mes išsprendžiame šią problemą taip:

ValueTask ir užduotis



Kaip minėta anksčiau, "ValueTask" naudojimas turi du pagrindinius privalumus:

  • Efektyvumu
  • Padidinkite įgyvendinimo lankstumą


Taigi, kokie yra našumo patobulinimų skaičiai? Laikykitės šio kodo:


Jei paleidžiame šį kodą, JIT vykdymui reikia 120 ns. Dabar, jei pakeisime užduotį į ValueTask taip:

Su JIT gausime 65 ns vykdymo laiką. Dabar tiesa, kad dėl "Task.Delay" mes nevykdome sinchroniškai, tačiau matome, kad pagerėjo vykdymo laikas.

Kitas mūsų minėtas privalumas yra didesnis įgyvendinimo lankstumas. Ką tai tiksliai reiškia? Na, asinchroninių sąsajų, kurios turėtų būti sinchronizuojamos, diegimas bus priverstas naudoti Task.Run arba Task.FromResult. Žinoma, tai lemia našumo problemas, kurias aptarėme anksčiau. Kai naudojame "ValueTask", labiau tikėtina, kad rinksimės sinchroninį arba asinchroninį diegimą. Atminkite, kad tai gali būti ženklas, kad jūsų kodas gali būti netinkamai sukurtas, jei taip nutiktų jums.

Pavyzdžiui, stebėkite šią sąsają:


Tarkime, kad norite jį iškviesti iš tokio kodo:

Kadangi sąsajoje naudojame "ValueTask", sąsajos įgyvendinimas gali būti sinchroninis arba asinchroninis. Mes galime gauti šią naudą iš esmės praleisdami pridedant kai kurias funkcijas į IThing, kad tvarkyti sinchronizavimo elgesį. Tokiu būdu naudoti šią sąsają yra daug lengviau. Čia yra sinchroninis aukščiau pateiktos sąsajos įgyvendinimas:

Štai asinchroninis tos pačios sąsajos įgyvendinimas:

Tačiau prieš naudodami "ValueTask" turime apsvarstyti kai kuriuos kompromisus. Nesunku pagalvoti, kad "ValueTask" turėtų būti naudojama pagal numatytuosius nustatymus, o ne "Task", o taip tikrai nėra. Pavyzdžiui, nors "ValueTask" padeda išvengti nereikalingų priskyrimų, kai galimas rezultatų sinchronizavimas, joje taip pat yra du laukai.

Svarbu prisiminti, kad tai yra struktūra, kurią čia naudojame, o tai reiškia, kad naudojame vertybių tipus ir visas jų naštas. Kita vertus, užduotis yra nuorodos tipas, turintis tik vieną lauką.Kai naudojate "ValueTask", turime daugiau duomenų, kuriuos turime apdoroti ir apdoroti. Jei tokio metodo laukiama asinchroniniu metodu, tada asinchroninis metodas yraValstybinė mašina taip pat bus didesnė, nes norint išsaugoti visą struktūrą paprastai reikia daugiau vietos nei saugoti vieną nuorodą.

Štai kodėl "Microsoft" žmonės iš tikrųjų rekomenduoja naudoti užduotį arba užduotį kaip numatytąjį asinchroninių metodų grąžinimo tipą. Tik atlikę našumo analizę turėtumėte apsvarstyti galimybę pereiti prie "ValueTask".


suvestinė

"ValueTask" yra .NET 4.7 įdiegta struktūra, suteikianti daug galimybių naudoti asinchroninius metodus .NET. Tačiau tai nėra be kainos. Tai naudinga našumui svarbiems metodams, kurie vykdomi sinchroniškai. Su jais galime išvengti nereikalingų objektų priskyrimo. Vis dėlto, kaip vertės tipas, jis turi visas problemas, su kuriomis paprastai susiduria vertybių tipai. Todėl mes galime gauti naudos iš šios struktūros, tačiau turime būti atsargūs.

Pradinis adresas:Hipersaito prisijungimas matomas.




Ankstesnis:【Praktinis veiksmas】 Naudokite "Docker", kad sukurtumėte IPsec VPN serverį
Kitą:Pasukite naudoti "OpenConnect", o ne "Cisco AnyConnect", kad išvengtumėte stalo užraktų nukreipimo
Publikuota: 2022-3-18 22:21:57 |
Ateikite mokytis dar kartą.
Paskelbta 2022-3-22 14:05:53 |
Sužinokite mokymosi esmęNeblogai
Atsakomybės apribojimas:
Visa programinė įranga, programavimo medžiaga ar straipsniai, kuriuos skelbia Code Farmer Network, yra skirti tik mokymosi ir mokslinių tyrimų tikslams; Aukščiau nurodytas turinys negali būti naudojamas komerciniais ar neteisėtais tikslais, priešingu atveju vartotojai prisiima visas pasekmes. Šioje svetainėje pateikiama informacija gaunama iš interneto, o ginčai dėl autorių teisių neturi nieko bendra su šia svetaine. Turite visiškai ištrinti aukščiau pateiktą turinį iš savo kompiuterio per 24 valandas nuo atsisiuntimo. Jei jums patinka programa, palaikykite autentišką programinę įrangą, įsigykite registraciją ir gaukite geresnes autentiškas paslaugas. Jei yra kokių nors pažeidimų, susisiekite su mumis el. paštu.

Mail To:help@itsvse.com