Programmering

Learning SynchronizationContext, async og afventer

Asynkron programmering er en form for parallel programmering, der giver dig mulighed for at udføre opgaver adskilt fra hovedapplikationstråden og derefter underrette tråden, når dens udførelse er slut. Asynchrony hjælper dig med at udføre opgaver uden behov for at holde udførelsesflowet eller lydhørheden af ​​din applikation.

Microsoft har ydet support til parallel programmering i .Net Framework for at udnytte fordelene ved multi-core-systemer. Du kan udnytte asynkroni for at forbedre din applikations ydeevne og lydhørhed.

I det væsentlige er der to mulige typer operationer i en applikation. Disse inkluderer computerbundne og I / O-bundne operationer. Beregningsbundne operationer er dem, hvor beregningen kan udføres på en separat tråd, så hovedtråden kan fortsætte med udførelsen. Tværtimod er I / O-bundne operationer dem, hvor de udføres eksternt, og derfor behøver de ikke at blokere den aktuelle tråd, mens I / O er i gang.

Synkroniseringskontekst og udførelseskontekst

Hver tråd har en sammenhæng tilknyttet - dette er også kendt som den "aktuelle" kontekst - og disse sammenhænge kan deles på tværs af tråde. ExecutionContext indeholder relevante metadata for det aktuelle miljø eller den aktuelle kontekst, hvor programmet udføres. SynchronizationContext repræsenterer en abstraktion - det angiver det sted, hvor din applikations kode udføres.

En SynchronizationContext giver dig mulighed for at sætte en opgave i kø i en anden kontekst. Bemærk, at hver tråd kan have sin egen SynchronizatonContext. SynchronizationContext-klassen er føjet for nylig til System.Threading-navneområdet og letter kommunikation mellem tråde. Du kan læse mere om SynchronizationContext og ExecutionContext her.

Et dybt dyk inde i Async og Await

De tre asynkrone programmeringsmønstre inkluderer følgende:

  1. Asynkron programmeringsmodel (APM)
  2. Begivenhedsbaseret asynkront mønster (EAP)
  3. Task-based Asynchronous Pattern (TAP)

Den seneste, den anbefalede og også den mest elegante af disse er TAP.

Bemærk, at du kan markere en metode ved hjælp af nøgleordet "async", der returnerer ugyldigt, opgave eller opgave. Bemærk, at når en undtagelse forekommer i en asynkron metode, der har en returtype af opgave eller opgave, gemmes undtagelsesoplysningerne i opgaveforekomsten.

Tværtimod, når en undtagelse forekommer inden i en asynkron metode, der har en returform af tomrum, gemmes undtagelsesoplysningerne inde i SynchronizationContext, der var aktiv på det tidspunkt, hvor den asynkrone metode blev kaldt. I det væsentlige kan du ikke håndtere undtagelser, der er rejst inden for en asynkron metode, der har en returtype ugyldig ved hjælp af undtagelsesbehandlere, der er skrevet i den asynkrone metode. På grund af de forskellige beregninger og fejlhåndteringssemantik tilrådes det at undgå asynkrone metoder, der har ugyldige returtyper, medmindre der er tilstrækkelig grund til at bruge dem.

Når du bruger nøgleordet "afventer" i en asynkron metode, opdeles metoden i en tilstandsmaskine. Bemærk, at nøgleordet "afventer" fanger den aktuelle SynchronizationContext, og så snart opgaven, der er afventet ved hjælp af nøgleordet "afventer", er afsluttet, genoptages tilstandsmaskinen, og udførelsen af ​​koden i opkaldsmetoden genstartes - dette er også kendt som fortsættelse. Hvis eksekvering af den kode, der er afventet ved hjælp af nøgleordet "afvente", er afsluttet på det tidspunkt, hvor suspensionspunktet er stødt, udføres den asynkrone metode (metoden, der er blevet markeret som "asynkroniseret") synkront. Hvis udførelsen af ​​den afventede kode ikke er færdig, vedhæftes en fortsættelsesdelegat til den afventede kode.

Du kan drage fordel af asynkrone metoder, der returnerer ugyldige for at oprette asynkrone hændelsesbehandlere. Main-metoden kan ikke markeres med nøgleordet "async", da det er applikationens indgangssted - en "async" -hovedmetode vil afslutte det øjeblik det kaldes. Nøgleordet "afvente" informerer kompilatoren om, at metoden kan have et suspensions- og genoptagelsespunkt. I øvrigt kan du kun bruge nøgleordet "afvente" på en metode, der er markeret som asynkron ved hjælp af nøgleordet "asynkronisering".

En asynkroniseringsmetode, når den kaldes, kører synkront på den aktuelle tråd uanset metoden for returneringstype. Når du markerer en metode som asynkron ved hjælp af nøgleordet "async", informerer du bare kompilatoren om, at metoden kan opdeles i flere opgaver - nogle af disse opgaver udføres muligvis asynkront. Inklusionen af ​​nøgleordet "async" i en metode sætter heller ikke køen til metoden som en del af trådpuljen. Asynkronien (dvs. om en metode ville have asynkron opførsel) afhænger faktisk af det suspensionspunkt, du har nævnt i din metode ved hjælp af nøgleordet "afventer". Hvis du ikke inkluderer "afvent" nøgleordet i en asynkron metode, vil hele metoden udføres synkront.