In nella maggior parte degli scenari, le variabili locali sono specifiche di un thread, pertanto i problemi associati a volatile
non sono necessari.
Questo cambia quando, come nel tuo esempio, è una variabile "catturata" - quando viene implementata silenziosamente come un campo in una classe generata dal compilatore. Quindi, in teoria, potrebbe essere essere volatile, ma nella maggior parte dei casi non varrebbe la complessità aggiuntiva.
In particolare, qualcosa come un Monitor
(alias lock
) con Pulse
ecc. Poteva farlo altrettanto bene, come qualsiasi altro numero di altri costrutti di threading.
Threading è difficile, e un loop attiva raramente è il modo migliore per gestirlo ...
Re di modifica ... secondThread.Join()
sarebbe la cosa più ovvia - ma se si vuole veramente utilizzare un token separato, vedi sotto. Il vantaggio di questo (su cose come ManualResetEvent
) è che non richiede nulla dal sistema operativo - è gestito esclusivamente all'interno della CLI.
using System;
using System.Threading;
static class Program {
static void WriteLine(string message) {
Console.WriteLine(Thread.CurrentThread.Name + ": " + message);
}
static void Main() {
Thread.CurrentThread.Name = "Main";
object syncLock = new object();
Thread thread = new Thread(DoStuff);
thread.Name = "DoStuff";
lock (syncLock) {
WriteLine("starting second thread");
thread.Start(syncLock);
Monitor.Wait(syncLock);
}
WriteLine("exiting");
}
static void DoStuff(object lockHandle) {
WriteLine("entered");
for (int i = 0; i < 10; i++) {
Thread.Sleep(500);
WriteLine("working...");
}
lock (lockHandle) {
Monitor.Pulse(lockHandle);
}
WriteLine("exiting");
}
}
fonte
2009-06-23 12:21:51
La variabile non è locale in questo caso! Piuttosto, è una variabile di istanza in una classe generata dal compilatore. –
Questa è una differenza semantica: in termini di codice, è una variabile locale che viene catturata ... –
Quello che vedo è una variabile locale che viene aggiornata in un thread diverso. E anche se so che il compilatore creerà una variabile di istanza della mia variabile locale, il pre-compilatore apparentemente non è o è troppo testardo per riconoscerlo. –