Hur man använder flertrådar med uppgifter i C #

Dataprogrammeringsuttrycket "tråd" är förkortning för körningstråd, där en processor följer en specificerad sökväg genom din kod. Konceptet att följa mer än en tråd åt gången introducerar ämnet multi-tasking och multi-threading.

En applikation har en eller flera processer i den. Tänk på en process som ett program som körs på din dator. Nu har varje process en eller flera trådar. En spelapplikation kan ha en tråd för att ladda resurser från disken, en annan för att göra AI och en annan för att köra spelet som en server.

I .NET / Windows fördelar operativsystemet processortid till en tråd. Varje tråd håller reda på undantagshanterare och den prioritet som den kör, och den har någonstans att spara trådkontexten tills den körs. Trådkontext är den information som tråden behöver återuppta.

Flera uppgifter med trådar

Trådar tar lite minne och det tar lite tid att skapa dem, så vanligtvis vill du inte använda många. Kom ihåg att de tävlar om processortid. Om din dator har flera CPU: er kan Windows eller .NET köra varje tråd på en annan CPU, men om flera trådar körs på samma CPU kan bara en vara aktiv i taget och att byta trådar tar tid.

CPU kör en tråd för några miljoner instruktioner, och sedan byter den till en annan tråd. Alla CPU-register, nuvarande programmets exekveringspunkt och stack måste sparas någonstans för den första tråden och sedan återställas från någon annanstans för nästa tråd.

Skapa en tråd

I namnområdet System. Trådande hittar du trådtypen. Konstruktörstråden (ThreadStart) skapar en instans av en tråd. Men i den senaste C # -koden är det mer troligt att det passerar ett lambda-uttryck som kallar metoden med några parametrar.

Om du är osäker på lambda-uttryck kan det vara värt att kolla in LINQ.

Här är ett exempel på en tråd som skapas och startas:

använder System;
använder System.Treading;
namnutrymme ex1

klassprogram

public static void Writ1 ()

Console.Write ('1');
Tråd. Sömn (500);

static void Main (string [] args)

var uppgift = ny tråd (skriv1);
uppgift.Start ();
för (var i = 0; i < 10; i++)

Console.Write ('0');
Console.Write (task.IsAlive? 'A': 'D');
Tråd. Sömn (150);

Konsol.ReadKey ();


Allt detta exempel gör är att skriva "1" till konsolen. Huvudtråden skriver en "0" till konsolen 10 gånger, varje gång följt av en "A" eller "D" beroende på om den andra tråden fortfarande är levande eller död.

Den andra tråden löper bara en gång och skriver en "1." Efter halv sekunders fördröjning i tråden Writ1 () slutar tråden och uppgiften.IsAlive i huvudslingan returnerar nu "D."

Trådpool och uppgiftsparallellbibliotek

Istället för att skapa din egen tråd, om du verkligen behöver göra det, använd en trådpool. Från .NET 4.0 har vi tillgång till Task Parallel Library (TPL). Som i föregående exempel behöver vi återigen lite LINQ, och ja, det är allt lambda-uttryck.

Uppgifterna använder trådpoolen bakom kulisserna men utnyttjar trådarna bättre beroende på antalet som används.

Huvudobjektet i TPL är en uppgift. Detta är en klass som representerar en asynkron operation. Det vanligaste sättet att börja saker som körs är med Task.Factory.StartNew som i: