Programiranje

Kako uporabljati ValueTask v jeziku C #

Asinhrono programiranje je v uporabi že kar nekaj časa. V zadnjih letih je postal močnejši z uvedbo ključnih besed async in await. Asinhrono programiranje lahko izkoristite za povečanje odzivnosti in prepustnosti aplikacije.

Priporočena vrsta vrnitve asinhrone metode v C # je Task. Vrnite Task, če želite napisati asinhrono metodo, ki vrne vrednost. Če želite napisati vodnik dogodkov, lahko namesto tega vrnete ničnost. Do C # 7.0 lahko asinhrona metoda vrne Task, Task ali void. Začenši s C # 7.0 lahko asinhrona metoda vrne tudi ValueTask (na voljo kot del paketa System.Threading.Tasks.Extensions) ali ValueTask. Ta članek predstavlja razpravo o tem, kako lahko delamo z ValueTask v jeziku C #.

Če želite delati s primeri kod v tem članku, morate imeti v sistemu nameščen Visual Studio 2019. Če kopije še nimate, lahko Visual Studio 2019 prenesete tukaj.

Ustvarite projektni program konzole .NET Core v Visual Studio

Najprej ustvarimo aplikacijski projekt konzole .NET Core v Visual Studio. Ob predpostavki, da je Visual Studio 2019 nameščen v vašem sistemu, sledite spodnjim korakom, da ustvarite nov aplikacijski projekt konzole .NET Core v Visual Studio.

  1. Zaženite Visual Studio IDE.
  2. Kliknite »Ustvari nov projekt«.
  3. V oknu »Ustvari nov projekt« na seznamu predlog izberite »Console App (.NET Core)«.
  4. Kliknite Naprej.
  5. V naslednjem oknu »Konfiguriranje novega projekta« določite ime in mesto novega projekta.
  6. Kliknite Ustvari.

Tako boste ustvarili nov aplikacijski projekt konzole .NET Core v Visual Studio 2019. Ta projekt bomo uporabili za ponazoritev uporabe ValueTask v naslednjih odsekih tega članka.

Zakaj naj uporabljam ValueTask?

Opravilo predstavlja stanje neke operacije, tj. Ali je operacija dokončana, preklicana itd. Asinhrona metoda lahko vrne Task ali ValueTask.

Ker je Task referenčna vrsta, vrnitev predmeta Task iz asinhrone metode pomeni dodelitev predmeta na upravljani kopici vsakič, ko je metoda poklicana. Tako je eno opozorilo pri uporabi opravila, da morate vsakič, ko iz metode vrnete predmet opravila, dodeliti pomnilnik v upravljani kopici. Če je rezultat operacije, ki jo izvede vaša metoda, na voljo takoj ali se dokonča sinhrono, ta dodelitev ni potrebna in zato postane draga.

Tukaj na pomoč priskoči ValueTask. ValueTask ponuja dve glavni prednosti. Prvič, ValueTask izboljša zmogljivost, ker ne potrebuje dodeljevanja kopice, drugič pa je enostaven in prilagodljiv za izvajanje. Če vrnete ValueTask namesto Task iz asinhrone metode, ko je rezultat takoj na voljo, se lahko izognete nepotrebnim režijskim stroškom dodeljevanja, saj "T" tukaj predstavlja strukturo, struktura v C # pa je vrsta vrednosti (v nasprotju s "T" v opravilu, ki predstavlja razred).

Task in ValueTask predstavljata dve primarni "čakljivi" vrsti v jeziku C #. Upoštevajte, da funkcije ValueTask ne morete blokirati. Če morate blokirati, morate pretvoriti ValueTask v opravilo z uporabo metode AsTask in nato blokirati za ta referenčni objekt.

Upoštevajte tudi, da lahko vsako ValueTask porabite samo enkrat. Tu beseda »porabi« pomeni, da lahko ValueTask asinhrono počaka (dočaka), da se operacija zaključi, ali pa AsTask izkoristi za pretvorbo ValueTask v opravilo. Vendar pa je treba ValueTask porabiti le enkrat, nato pa ValueTask prezreti.

Primer ValueTask v jeziku C #

Recimo, da imate asinhrono metodo, ki vrne opravilo. Lahko izkoristite Task.FromResult, da ustvarite objekt Task, kot je prikazano v spodnjem delčku kode.

javna naloga GetCustomerIdAsync ()

{

vrni Task.FromResult (1);

}

Zgornji delček kode ne ustvari celotne magije asinhrenega stroja, vendar v upravljanem kupu dodeli objekt Task. Da bi se izognili tej dodelitvi, boste morda želeli izkoristiti ValueTask, kot je prikazano v spodnjem delčku kode.

public ValueTask GetCustomerIdAsync ()

{

vrne novo ValueTask (1);

}

Naslednji delček kode ponazarja sinhrono izvajanje funkcije ValueTask.

 javni vmesnik IRepository

    {

ValueTask GetData ();

    }

Razred Repository razširja vmesnik IRepository in izvaja njegove metode, kot je prikazano spodaj.

  skladišče javnega razreda: IRepository

    {

public ValueTask GetData ()

        {

vrednost var = privzeto (T);

vrni novo ValueTask (vrednost);

        }

    }

Tukaj je opisano, kako lahko iz metode Main pokličete metodo GetData.

statična praznina Main (string [] args)

        {

Repozitorij IRepository = novo Repozitorij ();

var rezultat = repozitorij.GetData ();

if (result.IsCompleted)

Console.WriteLine ("Operacija je končana ...");

drugače

Console.WriteLine ("Operacija ni dokončana ...");

Console.ReadKey ();

        }

Zdaj v naše skladišče dodajte še eno metodo, tokrat asinhrono metodo z imenom GetDataAsync. Tukaj je, kako bi izgledal spremenjeni vmesnik IRepository.

javni vmesnik IRepository

    {

ValueTask GetData ();

ValueTask GetDataAsync ();

    }

Metodo GetDataAsync izvaja razred Repozitorij, kot je prikazano v spodnjem delčku kode.

  skladišče javnega razreda: IRepository

    {

public ValueTask GetData ()

        {

vrednost var = privzeto (T);

vrni novo ValueTask (vrednost);

        }

public async ValueTask GetDataAsync ()

        {

vrednost var = privzeto (T);

počakajte Task.Delay (100);

vrnjena vrednost;

        }

    }

Kdaj naj uporabim ValueTask v jeziku C #?

Kljub prednostim, ki jih ponuja ValueTask, obstajajo določeni kompromisi pri uporabi ValueTask namesto Task. ValueTask je vrsta vrednosti z dvema poljem, medtem ko je opravilo referenčna vrsta z enim samim poljem. Zato uporaba ValueTask pomeni delo z več podatki, saj bi klic metode vrnil dve polji podatkov namesto enega. Če čakate na metodo, ki vrne ValueTask, bi bil tudi državni stroj za to asinhrono metodo večji - ker bi moral v primeru opravila namestiti strukturo, ki vsebuje dve polji namesto ene reference.

Če potrošnik asinhrone metode uporabi Task.WhenAll ali Task.WhenAny, lahko uporaba ValueTask kot vrste vrnitve v asinhroni metodi postane draga. To je zato, ker bi morali ValueTask pretvoriti v opravilo z uporabo metode AsTask, kar bi povzročilo dodelitev, ki bi se ji zlahka izognili, če bi bila najprej uporabljena predpomnjena naloga.

Tu je pravilo palca. Uporabite opravilo, če imate del kode, ki bo vedno asinhron, tj. Ko operacija ne bo takoj končana. Izkoristite ValueTask, ko je rezultat asinhrone operacije že na voljo ali ko že imate predpomnjeni rezultat. Kakor koli že, pred razmislekom o ValueTask izvedite potrebno analizo učinkovitosti.

Kako narediti več v jeziku C #:

  • Kako uporabiti nespremenljivost v C
  • Kako uporabljati const, readonly in static v C #
  • Kako uporabljati pripise podatkov v jeziku C #
  • Kako delati z GUID-i v C # 8
  • Kdaj uporabiti abstraktni razred v primerjavi z vmesnikom v jeziku C #
  • Kako delati z AutoMapper v C #
  • Kako uporabljati lambda izraze v jeziku C #
  • Kako delati z delegati Action, Func in Predicate v C #
  • Kako delati z delegati v C #
  • Kako implementirati preprost zapisovalnik v jeziku C #
  • Kako delati z atributi v jeziku C #
  • Kako delati z log4net v C #
  • Kako implementirati vzorec oblikovanja repozitorija v C #
  • Kako delati z refleksijo v jeziku C #
  • Kako delati z nadzornikom datotek v C #
  • Kako izvesti leno inicializacijo v C #
  • Kako delati z MSMQ v C #
  • Kako delati z razširitvenimi metodami v jeziku C #
  • Kako do lambda izrazov v jeziku C #
  • Kdaj uporabiti hlapljivo ključno besedo v jeziku C #
  • Kako uporabiti ključno besedo yield v jeziku C #
  • Kako uporabiti polimorfizem v jeziku C #
  • Kako zgraditi lasten načrtovalnik opravil v C #
  • Kako delati z RabbitMQ v C #
  • Kako delati s korpico v jeziku C #
  • Raziskovanje virtualnih in abstraktnih metod v jeziku C #
  • Kako uporabljati Dapper ORM v C #
  • Kako uporabiti vzorec letenja v C #
$config[zx-auto] not found$config[zx-overlay] not found