Multithreading in C # con attività

click fraud protection

Il programmazione computer il termine "thread" è l'abbreviazione di thread di esecuzione, in cui un processore segue un percorso specificato attraverso il codice. Il concetto di seguire più di un thread alla volta introduce il tema del multi-tasking e del multi-threading.

Un'applicazione contiene uno o più processi. Pensa a un processo come a un programma in esecuzione sul tuo computer. Ora ogni processo ha uno o più thread. Un'applicazione di gioco potrebbe avere un thread per caricare risorse dal disco, un'altra per eseguire l'intelligenza artificiale e un'altra per eseguire il gioco come server.

In .NET / Windows, il sistema operativo alloca il tempo del processore a un thread. Ogni thread tiene traccia dei gestori delle eccezioni e della priorità con cui viene eseguito e ha un posto in cui salvare il contesto del thread fino a quando non viene eseguito. Il contesto del thread è l'informazione che il thread deve riprendere.

Multi-tasking con discussioni

I thread occupano un po 'di memoria e la loro creazione richiede un po' di tempo, quindi di solito non vuoi usarne molti. Ricorda, competono per il tempo del processore. Se il tuo computer ha più CPU, Windows o .NET potrebbero eseguire ogni thread su una CPU diversa, ma se più thread vengono eseguiti sulla stessa CPU, quindi solo uno può essere attivo alla volta e il passaggio dei thread richiede tempo.

instagram viewer

La CPU esegue un thread per qualche milione di istruzioni, quindi passa a un altro thread. Tutti i registri della CPU, l'attuale punto di esecuzione del programma e lo stack devono essere salvati da qualche parte per il primo thread e poi ripristinati da qualche altra parte per il thread successivo.

Creare una discussione

Nel sistema dello spazio dei nomi. Threading, troverai il tipo di thread. Il thread del costruttore (ThreadStart) crea un'istanza di un thread. Tuttavia, di recente C # codice, è più probabile che passi un'espressione lambda che chiama il metodo con qualsiasi parametro.

Se non sei sicuro espressioni lambda, potrebbe valere la pena dare un'occhiata a LINQ.

Ecco un esempio di thread creato e avviato:

utilizzando il sistema;
utilizzando il sistema. threading;
spazio dei nomi ex1
{
programma di classe
{
vuoto statico pubblico Write1 ()
{
Console. Scrivi ('1');
Filo. Sonno (500);
}
void statico Main (string [] args)
{
var task = new Thread (Write1);
compito. Inizio() ;
per (var i = 0; i <10; i ++)
{
Console. Scrivi ('0');
Console. Scrivi (compito. È vivo? 'ANNO DOMINI') ;
Filo. Sonno (150);
}
Console. ReadKey ();
}
}
}

Tutto questo esempio fa è scrivere "1" sulla console. Il thread principale scrive uno "0" sulla console 10 volte, ogni volta seguito da un "A" o "D" a seconda che l'altro thread sia ancora vivo o morto.

L'altro thread viene eseguito una sola volta e scrive un "1." Dopo il ritardo di mezzo secondo nel thread Write1 (), il thread termina e l'attività. IsAlive nel loop principale ora restituisce "D."

Libreria parallela di pool di thread e attività

Invece di creare il tuo thread, a meno che tu non abbia davvero bisogno di farlo, usa un pool di thread. Da .NET 4.0, abbiamo accesso alla Task Parallel Library (TPL). Come nell'esempio precedente, ancora una volta abbiamo bisogno di un po 'di LINQ, e sì, sono tutte espressioni lambda.

Attività utilizza il Pool di thread dietro le quinte ma fai un uso migliore dei thread a seconda del numero in uso.

L'oggetto principale nel TPL è un'attività. Questa è una classe che rappresenta un'operazione asincrona. Il modo più comune per avviare le attività è con l'attività. Fabbrica. Inizia come da:

Compito. Fabbrica. StartNew (() => DoSomething ());

Dove DoSomething () è il metodo che viene eseguito. È possibile creare un'attività e non eseguirla immediatamente. In tal caso, basta usare Task in questo modo:

var t = new Task (() => Console. WriteLine ( "Ciao"));
...
t. Inizio();

Ciò non avvia il thread fino a quando non viene chiamato .Start (). Nell'esempio seguente, sono cinque le attività.

utilizzando il sistema;
utilizzando il sistema. threading;
utilizzando il sistema. Threading. Compiti;
spazio dei nomi ex1
{
programma di classe
{
vuoto statico pubblico Write1 (int i)
{
Console. Scrivi (i);
Filo. Sonno (50);
}
void statico Main (string [] args)
{
per (var i = 0; i <5; i ++)
{
var value = i;
var runningTask = Task. Fabbrica. StartNew (() => Write1 (value));
}
Console. ReadKey ();
}
}
}

Eseguilo e ottieni le cifre da 0 a 4 in uscita in un ordine casuale come 03214. Questo perché l'ordine di esecuzione dell'attività è determinato da .NET.

Potresti chiederti perché è necessario var value = i. Prova a rimuoverlo e chiama Write (i) e vedrai qualcosa di inaspettato come 55555. Perchè è questo? È perché l'attività mostra il valore di i nel momento in cui l'attività viene eseguita, non quando l'attività è stata creata. Creando un nuovo variabile ogni volta nel ciclo, ciascuno dei cinque valori viene correttamente memorizzato e raccolto.

instagram story viewer