Programmering

På Task.Factory.StartNew og Task.Run metoder

Når du oppretter oppgaver ved hjelp av Task.Factory.StartNew eller Task.Run-metoder, bør du huske på visse viktige punkter når du skriver asynkron kode. I de fleste tilfeller er det tilrådelig å unngå å bruke Task.Factory.StartNew-metoden hvis du jobber med asynkron kode. Hvis du jobber med parallell kode, vil jeg si at StartNew er et godt valg.

En oppgaveplanlegger er en komponent som er ansvarlig for planlegging av oppgaver; Net Framework gir deg to oppgaveplanleggere. Det er standard oppgaveplanlegger som kjører på. Net framework thread thread pool, og det er oppgaveplanleggeren som kjøres på synkroniseringskonteksten til et spesifisert mål. Standard oppgaveplanlegger vil være tilstrekkelig mesteparten av tiden, men du kan også bygge din egen tilpassede oppgaveplanlegger for å gi ekstra funksjoner. For å bygge din egen tilpassede oppgaveplanlegger, må du opprette en klasse som utvider System.Threading.Tasks.TaskScheduler-klassen.

Hvordan lager jeg oppgaver ved hjelp av oppgaveparallellbiblioteket?

Det er flere måter du kan opprette og starte oppgaver på .Net. Du må bruke System.Threading.Tasks.Task eller System.Threading.Tasks.Task-klasse for å opprette oppgaver (en planleggbar arbeidsenhet). Mens førstnevnte brukes til å opprette en oppgave som ikke returnerer en verdi, brukes sistnevnte til å opprette oppgaver som har returverdier. Task.Factory-egenskapen er en forekomst av TaskFactory-klassen. Denne egenskapen brukes til å opprette og planlegge oppgaver. Mens Task.Factory.StartNew-metoden fungerer som en gaffeloperasjon og brukes til å opprette og starte nye oppgaver, fungerer Wait-metoden akkurat som en join-operasjon og venter på at oppgaven skal være fullført.

Følgende kodebit illustrerer hvordan du kan bruke metoden Task.Factory.StartNew.

Task.Factory.StartNew (() => TestMethod (), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);

Du kan også opprette en oppgave ved hjelp av Task.Run-metoden som vist i kodebiten nedenfor.

offentlig asynkronisering Oppgave DoSomeWork ()

        {

avvente Task.Run (() => TestMethod ());

        }

ugyldig TestMethod ()

        {

Console.WriteLine ("Hei verden!");

        }

Hvis du vil returnere en verdi fra en oppgave, kan du dra nytte av Task.FromResult-metoden som vist i kodebiten nedenfor.

offentlig asynkronisering Oppgave DoSomeWork ()

   {

strengtekst = avventer Task.FromResult (GetMessage ());

   }

privat streng GetMessage ()

   {

returner "Hallo verden!";

   }

Du kan også opprette oppgaver ved hjelp av en delegat eller en handling. Følgende kodebit viser hvordan du kan opprette oppgaver ved hjelp av handlinger og delegater.

Oppgave oppgave1 = ny oppgave (ny handling (skjerm));

oppgave1.Start ();

Oppgave task2 = ny oppgave (delegat {Display ();});

oppgave2.Start ();

Du kan også opprette oppgaver ved hjelp av lamba og anonyme metoder.

Task.Factory.StartNew og Task.Run

Task.Factory.StartNew er en rask måte å opprette og starte en oppgave på. Merk at et anrop til Task.Factory.StartNew tilsvarer funksjonelt å opprette en oppgaveforekomst og deretter kalle Start-metoden på forekomsten. Det anbefales imidlertid ikke å brukes av mange årsaker. Hvis du ønsker å utføre synkron kode, er ikke Task.Factory.StartNew et godt valg.

Merk at hvis en oppgaveplanlegger er tilgjengelig, vil StartNew-metoden utføre oppgaven på den oppgaveplanleggeren. Tvert imot, hvis en planlegger ikke er tilgjengelig, vil den utføre oppgaven på en trådgruppetråd. Det skal bemerkes at Task.Factory.StartNew som standard er TaskScheduler.Current og ikke TaskScheduler.Default.

Merk at et kall til Task.Run (handling) tilsvarer følgende utsagn: Task.Factory.StartNew (action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

Tvert imot tilsvarer en samtale til Task.Factory.StartNew (handling) følgende utsagn:

Task.Factory.StartNew (action, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Current);

Hvis det er lurt å bruke Task.Factory.StartNew hvis du har opprettet en tilpasset oppgaveplanlegger og sender planleggerforekomsten eksplisitt til den. Jeg vil alltid anbefale å bruke Task.Run da det er mye enklere og har tryggere standardinnstillinger. Med andre ord, bør vi unngå å bruke Task.Factory.StartNew med mindre det er behov for å opprette en oppgaveplanlegger og deretter sende den eksplisitt når du ringer til StartNew-metoden for å opprette en ny oppgave og planlegge den. Hvis du skulle bruke TaskFactory.StartNew-metoden effektivt og pålitelig, bør du bruke en tilpasset oppgaveplanlegger og deretter spesifisere CancellationToken og TaskCreationOptions.

Task.Run-metoden anbefales å bruke når du ikke trenger å ha mye finkornet kontroll over trådplanlegging og dens komplikasjoner. Du bør bruke Task.Run primært på CPU-bundne metoder. Du bør imidlertid bruke Task.Run mens du påkaller oppgaven og ikke inne i gjennomføringen av oppgaven. Med andre ord, bør du bruke Task.Run ikke i noen implementering av en metode, men på det punktet der metoden kalles. Som et eksempel er følgende kodebit et eksempel på en "dårlig" kode.

offentlig asynk Oppgave Last nedDataFromWebAsync (Uri uri)

        {

retur venter Task.Run (() =>

            {

bruker (WebClient webClient = new WebClient ())

                {

return webClient.DownloadString (uri);

                }

            });

        }

Se kodebiten gitt ovenfor. Metoden er ikke skalerbar, da den vil blokkere bakgrunnstråden, hente en tråd fra trådbassenget og utføre synkront på den. Derfor vil det forbruke flere ressurser i systemet ditt.

$config[zx-auto] not found$config[zx-overlay] not found