Multi-threading i C # With Tasks

Det computer programmering udtrykket "tråd" er en forkortelse for udførelsestråd, hvor en processor følger en specificeret sti gennem din kode. Konceptet med at følge mere end en tråd ad gangen introducerer emnet multi-tasking og multi-threading.

En applikation har en eller flere processer i sig. Tænk på en proces som et program, der kører på din computer. Nu har hver proces en eller flere tråde. Et spilprogram kan have en tråd til at indlæse ressourcer fra disken, en anden til at gøre AI og en anden til at køre spillet som en server.

I .NET / Windows tildeler operativsystemet processortid til en tråd. Hver tråd holder styr på undtagelsesbehandlere og den prioritet, hvorpå den kører, og den har et sted at gemme trådkonteksten, indtil den kører. Trådkontekst er de oplysninger, som tråden skal genoptages.

Multi-opgave med tråde

Tråde optager lidt hukommelse, og at oprette dem tager lidt tid, så som regel ønsker du ikke at bruge mange. Husk, at de konkurrerer om processortid. Hvis din computer har flere CPU'er, kører Windows eller .NET muligvis hver tråd på en anden CPU, men hvis adskillige tråde kører på den samme CPU, så er det kun én, der kan være aktiv ad gangen, og at skifte tråde tager tid.

instagram viewer

CPU'en kører en tråd for et par millioner instruktioner, og derefter skifter den til en anden tråd. Alle CPU-registre, det aktuelle programudførelsespunkt og stak skal gemmes et sted for den første tråd og derefter gendannes fra et andet sted for den næste tråd.

Oprettelse af en tråd

I navneområdet System. Threading, finder du trådtypen. Konstruktortråden (ThreadStart) opretter en forekomst af en tråd. Dog i det seneste C # kode, er det mere sandsynligt, at det passerer et lambda-udtryk, der kalder metoden med eventuelle parametre.

Hvis du er usikker lambda-udtryk, kan det være værd at tjekke LINQ.

Her er et eksempel på en tråd, der oprettes og startes:

ved hjælp af system;
ved hjælp af System. threading;
navneområde ex1
{
klasse Program
{
offentlig statisk tomrum Skriv1 ()
{
Konsol. Skriv ('1');
Tråd. Søvn (500);
}
statisk tomrum Main (streng [] args)
{
var opgave = ny tråd (Skriv1);
opgave. Start() ;
for (var i = 0; i <10; i ++)
{
Konsol. Skriv ('0');
Konsol. Skriv (opgave. Er i live? 'A': 'D');
Tråd. Søvn (150);
}
Konsol. ReadKey ();
}
}
}

Alt dette eksempel gør er at skrive "1" til konsollen. Hovedtråden skriver en "0" til konsollen 10 gange, hver gang efterfulgt af en "A" eller "D" afhængigt af om den anden tråd stadig er levende eller død.

Den anden tråd kører kun én gang og skriver et "1." Efter halv sekunders forsinkelse i Writ1 () -tråden afsluttes tråden og opgaven. IsAlive i hovedsløjfen returnerer nu "D."

Trådpulje og opgave Parallelt bibliotek

I stedet for at oprette din egen tråd, medmindre du virkelig har brug for det, skal du bruge en trådpulje. Fra .NET 4.0 har vi adgang til Task Parallel Library (TPL). Som i det foregående eksempel har vi igen brug for lidt LINQ, og ja, det er alt lambda-udtryk.

Opgaver bruger Gevind pool bag kulisserne, men gør bedre brug af trådene afhængigt af antallet i brug.

Det vigtigste objekt i TPL er en opgave. Dette er en klasse, der repræsenterer en asynkron operation. Den mest almindelige måde at starte tingene på er med opgaven. Fabrik. StartNy som i:

Opgave. Fabrik. StartNew (() => DoSomething ());

Hvor DoSomething () er den metode, der køres. Det er muligt at oprette en opgave og ikke have den kørt med det samme. I så fald skal du bare bruge Opgave sådan:

var t = new Opgave (() => Konsol. WriteLine ( "Hello"));
...
t. Start();

Det starter ikke tråden, før .Start () kaldes. I eksemplet herunder er fem opgaver.

ved hjælp af system;
ved hjælp af System. threading;
ved hjælp af System. Threading. Opgaver;
navneområde ex1
{
klasse Program
{
offentlig statisk tomrum Skriv1 (int i)
{
Konsol. Skriv (i);
Tråd. Søvn (50);
}
statisk tomrum Main (streng [] args)
{
for (var i = 0; i <5; i ++)
{
var-værdi = i;
var runningTask = Opgave. Fabrik. StartNew (() => Skriv1 (værdi));
}
Konsol. ReadKey ();
}
}
}

Kør det, og du får cifrene 0 til 4 i en tilfældig rækkefølge, f.eks. 03214. Det skyldes, at rækkefølgen af ​​udførelse af opgave bestemmes af .NET.

Du spekulerer måske på, hvorfor var-værdien = i er nødvendig. Prøv at fjerne det og kalde Skriv (i), så ser du noget uventet som 55555. Hvorfor er det? Det er fordi opgaven viser værdien af ​​i på det tidspunkt, hvor opgaven udføres, ikke når opgaven blev oprettet. Ved at oprette en ny variabel hver gang i løkken er hver af de fem værdier korrekt gemt og afhent.

instagram story viewer