Programmēšana

Kā izmantot ValueTask C #

Asinhronā programmēšana ir izmantota jau diezgan ilgu laiku. Pēdējos gados tas ir kļuvis jaudīgāks, ieviešot asinhronizācijas un gaidīšanas atslēgvārdus. Lai palielinātu lietojumprogrammas atsaucību un caurlaidspēju, varat izmantot asinhronās programmēšanas priekšrocības.

Ieteicamais asinhronās metodes atgriešanas veids C # ir uzdevums. Jums jāatgriež uzdevums, ja vēlaties uzrakstīt asinhronu metodi, kas atgriež vērtību. Ja vēlaties rakstīt notikumu apstrādātāju, tā vietā varat atgriezties anulēts. Līdz C # 7.0 asinhronā metode varētu atgriezt uzdevumu, uzdevumu vai anulēt. Sākot ar C # 7.0, asinhronā metode var atgriezt arī ValueTask (pieejams kā paketes System.Threading.Tasks.Extensions pakotne) vai ValueTask. Šis raksts piedāvā diskusiju par to, kā mēs varam strādāt ar ValueTask C #.

Lai strādātu ar šajā rakstā sniegtajiem kodu piemēriem, sistēmā jābūt instalētai Visual Studio 2019. Ja jums vēl nav kopijas, varat lejupielādēt Visual Studio 2019 šeit.

Visual Studio izveidojiet .NET Core konsoles lietojumprogrammas projektu

Vispirms izveidosim .NET Core konsoles lietojumprogrammas projektu Visual Studio. Pieņemot, ka Visual Studio 2019 ir instalēta jūsu sistēmā, veiciet tālāk norādītās darbības, lai Visual Studio izveidotu jaunu .NET Core konsoles lietojumprogrammas projektu.

  1. Palaidiet Visual Studio IDE.
  2. Noklikšķiniet uz “Izveidot jaunu projektu”.
  3. Logā “Izveidot jaunu projektu” parādīto veidņu sarakstā atlasiet “Console App (.NET Core)”.
  4. Noklikšķiniet uz Tālāk.
  5. Nākamajā logā “Konfigurēt jauno projektu” norādiet jaunā projekta nosaukumu un vietu.
  6. Noklikšķiniet uz Izveidot.

Tādējādi Visual Studio 2019 tiks izveidots jauns .NET Core konsoles lietojumprogrammas projekts. Mēs izmantosim šo projektu, lai ilustrētu ValueTask izmantošanu šī raksta nākamajās sadaļās.

Kāpēc man vajadzētu izmantot ValueTask?

Uzdevums attēlo kādas operācijas stāvokli, t.i., vai darbība ir pabeigta, atcelta utt. Asinhronā metode var atgriezt uzdevumu vai ValueTask.

Tā kā uzdevums ir atsauces tips, uzdevuma objekta atgriešana no asinhronas metodes nozīmē objekta piešķiršanu pārvaldītajā kaudzē katru reizi, kad tiek izsaukta metode. Tādējādi viens uzdevuma izmantošanas brīdinājums ir tas, ka jums ir jāpiešķir atmiņa pārvaldītajā kaudzē katru reizi, kad atgriežat uzdevuma objektu no savas metodes. Ja ar jūsu metodi veiktās operācijas rezultāts ir pieejams uzreiz vai tiek pabeigts sinhroni, šī piešķiršana nav nepieciešama, un tāpēc tā kļūst dārga.

Šeit precīzi nāk palīgā ValueTask. ValueTask sniedz divas galvenās priekšrocības. Pirmkārt, ValueTask uzlabo veiktspēju, jo tai nav nepieciešams piešķirt kaudzi, un, otrkārt, to ir viegli un elastīgi ieviest. Atgriežot ValueTask uzdevuma vietā no asinhronas metodes, kad rezultāts ir uzreiz pieejams, varat izvairīties no nevajadzīgas piešķīruma pieskaitāmās izmaksas, jo “T” šeit apzīmē struktūru un struktūra C # ir vērtības tips (atšķirībā no “T”) (kas pārstāv klasi).

Uzdevums un ValueTask ir divi galvenie “gaidāmie” veidi C #. Ņemiet vērā, ka ValueTask nevar bloķēt. Ja jums ir nepieciešams bloķēt, ValueTask jāpārvērš par uzdevumu, izmantojot AsTask metodi, un pēc tam bloķējiet šo atsauces uzdevuma objektu.

Ņemiet vērā arī to, ka katru ValueTask var lietot tikai vienu reizi. Šeit vārds “patērēt” nozīmē, ka ValueTask var asinhroni gaidīt (gaidīt) operācijas pabeigšanu vai izmantot AsTask priekšrocības, lai ValueTask pārveidotu par uzdevumu. Tomēr ValueTask vajadzētu patērēt tikai vienu reizi, pēc tam ValueTask ir jāignorē.

ValueTask piemērs C #

Pieņemsim, ka jums ir asinhrona metode, kas atgriež uzdevumu. Jūs varat izmantot Task.FromResult priekšrocības, lai izveidotu objektu Task, kā parādīts tālāk sniegtajā koda fragmentā.

publiskais uzdevums GetCustomerIdAsync ()

{

atgriezties Task.FromResult (1);

}

Iepriekš minētais koda fragments nerada visu asinhronā stāvokļa mašīnas maģiju, taču tas piešķir Task objektu pārvaldītajā kaudzē. Lai izvairītos no šī sadalījuma, ieteicams izmantot ValueTask, kā parādīts tālāk sniegtajā koda fragmentā.

publiskā ValueTask GetCustomerIdAsync ()

{

atgriezt jaunu ValueTask (1);

}

Šis koda fragments ilustrē sinhronu ValueTask ieviešanu.

 publiskā saskarne IR krātuve

    {

ValueTask GetData ();

    }

Repository klase paplašina IRepository saskarni un ievieš tās metodes, kā parādīts zemāk.

  publiskās klases krātuve: IR krātuve

    {

publiskā ValueTask GetData ()

        {

var vērtība = noklusējums (T);

atgriezt jaunu ValueTask (vērtība);

        }

    }

Lūk, kā jūs varat izsaukt GetData metodi no galvenās metodes.

static void Main (virkne [] args)

        {

IR krātuves krātuve = jauna krātuve ();

var rezultāts = repozitorijs.GetData ();

ja (rezultāts.IsCompleted)

Console.WriteLine ("Darbība pabeigta ...");

cits

Console.WriteLine ("Darbība nav pabeigta ...");

Console.ReadKey ();

        }

Tagad pievienosim savai krātuvei vēl vienu metodi, šoreiz asinhrono metodi ar nosaukumu GetDataAsync. Lūk, kā izskatītos modificētā IRepository saskarne.

publiskā saskarne IR krātuve

    {

ValueTask GetData ();

ValueTask GetDataAsync ();

    }

GetDataAsync metodi ievieš repozitorija klase, kā parādīts tālāk sniegtajā koda fragmentā.

  publiskās klases krātuve: IR krātuve

    {

publiskā ValueTask GetData ()

        {

var vērtība = noklusējums (T);

atgriezt jaunu ValueTask (vērtība);

        }

publiskais asinhronais ValueTask GetDataAsync ()

        {

var vērtība = noklusējums (T);

gaidiet Uzdevums. Aizkave (100);

atgriešanās vērtība;

        }

    }

Kad man C # vajadzētu izmantot ValueTask?

Lai arī ValueTask sniedz priekšrocības, tomēr ir zināmi kompromisi, ja ValueTask lieto uzdevuma vietā. ValueTask ir vērtības tips ar diviem laukiem, savukārt uzdevums ir atsauces tips ar vienu lauku. Tādējādi ValueTask izmantošana nozīmē darbu ar vairāk datiem, jo ​​metodes izsaukums atgrieztu divus datu laukus viena vietā. Turklāt, ja jūs gaida metodi, kas atgriež ValueTask, arī šīs asinhronās metodes stāvokļa mašīna būtu lielāka - jo tai būtu jāiekļauj struktūra, kurā uzdevuma gadījumā vienā atsaucē ir divi lauki.

Turklāt, ja asinhronas metodes patērētājs izmanto Task.WhenAll vai Task.WhenAny, ValueTask izmantošana kā atgriešanās veidu asinhronā metodē var kļūt dārga. Tas ir tāpēc, ka jums būtu jāpārvērš ValueTask par uzdevumu, izmantojot AsTask metodi, kas radītu piešķīrumu, no kura varētu viegli izvairīties, ja kešatmiņā saglabātā uzdevums būtu izmantots vispirms.

Šeit ir īkšķa noteikums. Izmantojiet uzdevumu, ja jums ir koda daļa, kas vienmēr būs asinhrona, t.i., kad darbība netiks nekavējoties pabeigta. Izmantojiet ValueTask priekšrocības, kad asinhronas darbības rezultāts jau ir pieejams vai kad jums jau ir kešatmiņā saglabāts rezultāts. Jebkurā gadījumā pirms ValueTask apsvēršanas jums jāveic nepieciešamā veiktspējas analīze.

Kā izdarīt vairāk C #:

  • Kā izmantot nemainīgumu C
  • Kā lietot const, tikai lasāmu un statisku C #
  • Kā izmantot datu anotācijas C #
  • Kā strādāt ar GUID C # 8
  • Kad izmantot abstraktu klasi un saskarni C #
  • Kā strādāt ar AutoMapper C #
  • Kā lietot lambda izteicienus C #
  • Kā strādāt ar Action, Func un Predicate delegātiem C #
  • Kā strādāt ar delegātiem C #
  • Kā ieviest vienkāršu reģistrētāju C #
  • Kā strādāt ar atribūtiem C #
  • Kā strādāt ar log4net C #
  • Kā ieviest krātuves dizaina modeli C #
  • Kā strādāt ar refleksiju C #
  • Kā strādāt ar filesystemwatcher C #
  • Kā veikt slinku inicializāciju C #
  • Kā strādāt ar MSMQ C #
  • Kā strādāt ar paplašināšanas metodēm C #
  • Kā mums izteikt lambda izteicienus C #
  • Kad lietot svārstīgo atslēgvārdu C #
  • Kā izmantot ienesīguma atslēgvārdu C #
  • Kā ieviest polimorfismu C #
  • Kā izveidot savu uzdevumu plānotāju C #
  • Kā strādāt ar RabbitMQ C #
  • Kā strādāt ar dubultošanos C #
  • Virtuālu un abstraktu metožu izpēte C #
  • Kā lietot Dapper ORM C #
  • Kā izmantot lidojošā dizaina rakstu C #
$config[zx-auto] not found$config[zx-overlay] not found