Programmering

Bedste fremgangsmåder inden for .Net asynkron programmering

Asynkron programmering giver dig mulighed for at udføre ressourceintensive I / O-operationer uden at skulle blokere på applikationens hoved- eller udførelsestråd. Selvom det er gavnligt og tilsyneladende let at implementere, kommer det med meget kompleksitet og risici. De potentielle risici forbundet med asynkroniseringsprogrammering, især ved brug af asynkron programmering på den forkerte måde ved ikke at følge de anbefalede fremgangsmåder, inkluderer deadlocks, procesnedbrud og endda langsom ydeevne. Du skal også være dygtig til at skrive, debugge async-kode.

Undgå at have ugyldig returneringstype i asynkroniseringsmetoder

En metode i C # er lavet til en asynkron metode ved hjælp af async-nøgleordet i metodesignaturen. Du kan have et eller flere afventede nøgleord i en async-metode. Det ventede nøgleord bruges til at betegne suspensionspunktet. En asynkroniseringsmetode i C # kan have en hvilken som helst af disse returtyper: Opgave, Opgave og ugyldig. Nøgleordet "afvente" bruges i en asynkroniseringsmetode til at informere kompilatoren om, at metoden kan have et suspensions- og genoptagelsespunkt.

Bemærk, at når du bruger TPL, er ækvivalenten med at returnere ugyldigt i TPL async Task. Du skal være opmærksom på, at asynkroniseret tomrum kun er og skal bruges til asynkroniseringshændelser. Hvis du bruger det et andet sted, vil du støde på fejl. Med andre ord anbefales en asynkroniseringsmetode, der er ugyldig som returtype, ikke. fordi asynkroniseringsmetoder, der returnerer ugyldige, har forskellige semantik, når du arbejder med undtagelser i din applikation.

Når en undtagelse forekommer i en asynkroniseringsmetode, der har en returtype af opgave eller opgave, gemmes undtagelsesobjektet inde i opgaveobjektet. Tværtimod, hvis du har en asynkroniseringsmetode med en returform af tomrum, er der ikke noget opgaveobjekt tilknyttet. Sådanne undtagelser hæves på SynchronizationContext, der var aktiv på det tidspunkt, hvor den asynkrone metode blev kaldt. Med andre ord kan du ikke håndtere undtagelser, der er rejst inden for en asynkron ugyldig metode ved hjælp af undtagelsesbehandlere, der er skrevet inden for den asynkrone metode. Async-metoder, der har en returform af tomrum, er også vanskelige at teste på grund af denne forskel i fejlhåndtering af semantik. Til din information repræsenterer SynchronizationContext-klassen i System.Threading-navneområdet en synkroniseringskontekst i .Net og hjælper dig med at sætte en opgave i kø i en anden kontekst.

Følgende kodeliste illustrerer dette. Du har to metoder, nemlig Test og TestAsync, og sidstnævnte kaster en undtagelse.

offentlig klasse AsyncDemo

   {

offentlig ugyldig test ()

       {

prøve

           {

TestAsync ();

           }

fangst (undtagelse ex)

           {

Console.WriteLine (f.eks. Besked);

           }

       }

privat async ugyldigt TestAsync ()

       {

smid ny undtagelse ("Dette er en fejlmeddelelse");

       }

   }

Her er hvordan du kan oprette en forekomst af AsyncDemo-klassen og påberåbe sig testmetoden.

statisk ugyldigt Main (streng [] args)

       {

AsyncDemo obj = ny AsyncDemo ();

obj.Test ();

Console.Read ();

       }

Testmetoden foretager et opkald til TestAsync-metoden, og opkaldet pakkes ind i en prøvefangsblok med det formål at håndtere den undtagelse, der kastes inde i TestAsync-metoden. Dog undtages undtagelsen, der kastes inde i TestAsync-metoden, dvs. håndteres inde i opkaldsmetoden Test.

Undgå at blande asynkron og synkron kode

Du bør aldrig have en blanding af synkron og asynkron kode. Det er en dårlig programmeringspraksis at blokere for async-kode ved at foretage opkald til Task.Wait eller Task.Result. Jeg vil anbefale at bruge async-kode fra ende til anden - det er den sikreste måde at undgå fejl i at krybe ind.

Du kan undgå blokeringer ved hjælp af.ConfigureAwait (continueOnCapturedContext: false) når du ringer til at vente. Hvis du ikke bruger dette, blokerer async-metoden på det sted, hvor ventetiden er blevet kaldt. I dette tilfælde informerer du bare tjeneren om ikke at fange den aktuelle kontekst. Jeg vil sige, at det er en god praksis at bruge .ConfigureAwait (false), medmindre du har en specifik grund til ikke at bruge det.

Jeg vil diskutere mere om asynkron programmering i mine fremtidige blogindlæg her. For mere information om bedste praksis inden for asynkron programmering kan du henvise til Stephen Clearys store artikel på MSDN.