Come lavorare con i thread in C #

Un thread è la più piccola unità di esecuzione all'interno di un processo. Il multithreading è la capacità di avere più thread in memoria in un dato momento e di passare da uno all'altro per gestire più operazioni contemporaneamente. .Net Framework di Microsoft fornisce un eccellente supporto per lavorare con i thread.

Thread di programmazione in C #

Per lavorare con i thread, dovresti includere lo spazio dei nomi System.Threading nella tua applicazione. Per creare un nuovo thread, è necessario sfruttare il delegato ThreadStart e passare il riferimento a un metodo che dovrebbe essere eseguito sul thread. Si noti che un delegato è un puntatore a funzione indipendente dai tipi. Il frammento di codice seguente mostra come creare un nuovo oggetto thread usando questo delegato.

 Thread t = nuovo thread (nuovo ThreadStart (MyThreadMethod)); 

Per avviare il thread appena creato, dovresti chiamare il metodo Start sull'oggetto thread che hai creato. Il listato di codice seguente lo illustra. Si noti che il metodo del thread MyThreadMethod viene eseguito sul nuovo thread (chiamato thread di lavoro) che è stato creato.

 static void Main ()

        {

            Thread t = nuovo thread (nuovo ThreadStart (MyThreadMethod));

            t.Start ();           

            Console.Read ();

        }

        static void MyThreadMethod ()

        {

            Console.WriteLine ("Hello World!");

        }

Visualizza gli stati del thread in C #

Un thread in memoria può trovarsi in stati diversi: Aborted, Background, Running, Stopped, Suspended, Unstarted e così via. Gli stati dei thread sono definiti nell'enumerazione ThreadState disponibile nello spazio dei nomi System.Threading. A meno che il metodo Start non venga chiamato su un thread, il thread è nello stato Unstarted. Quando il metodo Start viene richiamato sull'istanza del thread, lo stato del thread cambia da Unstarted a Running.

Il frammento di codice seguente mostra come visualizzare lo stato di un thread nella console.

 Thread t = nuovo thread (nuovo ThreadStart (MyThreadMethod));

t.Start ();

Console.WriteLine ("Lo stato del thread è:" + t.ThreadState.ToString ());

Controllare i thread in primo piano e in background in C #

I thread possono essere eseguiti in primo piano o in background. I thread che crei in modo esplicito sono thread in primo piano. Una delle principali differenze tra un thread in primo piano e un thread in background è che l'applicazione è attiva solo finché uno o più thread in primo piano sono in esecuzione. In sostanza, i thread in primo piano impediscono la chiusura dell'applicazione. Al contrario, i thread in background non mantengono vivo l'ambiente Common Language Runtime.

È possibile impostare lo stato in background di un thread utilizzando la proprietà IsBackground. Ecco un esempio di codice che mostra come questo può essere ottenuto.

 static void Main ()

        {

            Thread t = nuovo thread (nuovo ThreadStart (MyThreadMethod));

            t.Start ();

            t.IsBackground = true;

            Console.WriteLine ("Lo stato in background del thread è:" + t.IsBackground.ToString ());

            Console.Read ();

        }

È possibile sospendere o riprendere un thread invocando i metodi Suspend () e Resume () sull'oggetto thread. Nota che puoi solo riprendere un thread che avevi precedentemente sospeso effettuando una chiamata al metodo Suspend ().

 Thread t = nuovo thread (nuovo ThreadStart (MyThreadMethod));

t.Start ();

t.Suspend (); // Sospende il thread appena creato

t.Resume (); // Riprende il thread sospeso

Tuttavia, va notato che i metodi Thread.Suspend () e Thread.Resume () sono stati deprecati. Piuttosto, dovresti usare i metodi AutoResetEvent e EventWaitHandle per sincronizzare le attività che coinvolgono i thread.

Imposta la priorità del thread in C #

È possibile controllare la priorità di un thread per determinare la quota relativa del tempo del processore che un thread otterrà rispetto agli altri thread che risiedono nella memoria. La priorità del thread è definita nell'enumerazione ThreadPriority. I valori possibili includono: Lowest, BelowNormal, Normal, AboveNormal e Highest. Il frammento di codice seguente illustra come impostare le priorità dei thread di due thread utilizzando la proprietà Priority dell'oggetto thread.

 static void Main ()

        {

            Thread thread1 = nuovo thread (nuovo ThreadStart (Method1));

            Thread thread2 = nuovo thread (nuovo ThreadStart (Method2));

            thread1.Priority = ThreadPriority.Highest;

            thread2.Priority = ThreadPriority.Lowest;

            thread2.Start ();

            thread1.Start ();

            Console.Read ();

        }

        static void Method1 ()

        {

            for (int i = 0; i <10; i ++)

            {

                Console.WriteLine ("Primo thread:" + i);

            }

        }

        static void Method2 ()

        {

            for (int i = 0; i <10; i ++)

            {

                Console.WriteLine ("Secondo thread:" + i);

            }

        }

Quando si esegue il frammento di codice sopra, vedrai che il primo thread completa la sua esecuzione prima del secondo thread anche se il secondo thread è stato avviato prima del primo thread nel metodo Main.

I fili sono costosi. Consumano molte risorse nel sistema per l'inizializzazione, il cambio di contesto e il rilascio delle risorse che consumano. Di conseguenza il multithreading dovrebbe essere usato con giudizio e solo quando è necessario. Quando si traggono vantaggio dal multithreading, è sempre consigliabile sfruttare i pool di thread per creare e gestire i thread su richiesta e migliorare la reattività dell'applicazione.