Stavo leggendo il post tips and tricks e ho pensato di provare alcune delle cose di C# che non avevo mai fatto prima. Pertanto, il seguente codice non ha alcun scopo reale, ma è solo una 'funzione di test' per vedere cosa succede.C# ThreadStatic + membri volatili che non funzionano come previsto
In ogni caso, ho due campi privati statici:
private static volatile string staticVolatileTestString = "";
[ThreadStatic]
private static int threadInt = 0;
Come potete vedere, sto testando ThreadStaticAttribute e la volatilità parola chiave .
Comunque, ho un metodo di prova che assomiglia a questo:
private static string TestThreadStatic() {
// Firstly I'm creating 10 threads (DEFAULT_TEST_SIZE is 10) and starting them all with an anonymous method
List<Thread> startedThreads = new List<Thread>();
for (int i = 0; i < DEFAULT_TEST_SIZE; ++i) {
Thread t = new Thread(delegate(object o) {
// The anon method sets a newValue for threadInt and prints the new value to the volatile test string, then waits between 1 and 10 seconds, then prints the value for threadInt to the volatile test string again to confirm that no other thread has changed it
int newVal = randomNumberGenerator.Next(10, 100);
staticVolatileTestString += Environment.NewLine + "\tthread " + ((int) o) + " setting threadInt to " + newVal;
threadInt = newVal;
Thread.Sleep(randomNumberGenerator.Next(1000, 10000));
staticVolatileTestString += Environment.NewLine + "\tthread " + ((int) o) + " finished: " + threadInt;
});
t.Start(i);
startedThreads.Add(t);
}
foreach (Thread th in startedThreads) th.Join();
return staticVolatileTestString;
}
Quello che mi aspetto di vedere tornato da questa funzione è un output come questo:
thread 0 setting threadInt to 88
thread 1 setting threadInt to 97
thread 2 setting threadInt to 11
thread 3 setting threadInt to 84
thread 4 setting threadInt to 67
thread 5 setting threadInt to 46
thread 6 setting threadInt to 94
thread 7 setting threadInt to 60
thread 8 setting threadInt to 11
thread 9 setting threadInt to 81
thread 5 finished: 46
thread 2 finished: 11
thread 4 finished: 67
thread 3 finished: 84
thread 9 finished: 81
thread 6 finished: 94
thread 7 finished: 60
thread 1 finished: 97
thread 8 finished: 11
thread 0 finished: 88
Tuttavia, ciò che sto ottenendo è questa:
thread 0 setting threadInt to 88
thread 4 setting threadInt to 67
thread 6 setting threadInt to 94
thread 7 setting threadInt to 60
thread 8 setting threadInt to 11
thread 9 setting threadInt to 81
thread 5 finished: 46
thread 2 finished: 11
thread 4 finished: 67
thread 3 finished: 84
thread 9 finished: 81
thread 6 finished: 94
thread 7 finished: 60
thread 1 finished: 97
thread 8 finished: 11
thread 0 finished: 88
la seconda 'meta' l'uscita è come previsto (che suppongo mezzi ° al campo ThreadStatic funziona come pensavo), ma sembra che alcune delle uscite iniziali siano state "saltate" dalla prima "metà".
Inoltre, i thread nel primo "mezzo" sono fuori servizio, ma ho capito che un thread non viene eseguito immediatamente non appena si chiama Start(); ma invece i controlli interni del sistema operativo inizieranno i thread come meglio crede.
EDIT: No non stanno, in realtà, ho solo pensato che fossero perché il mio cervello manca i numeri consecutivi
Quindi, la mia domanda è: cosa sta andando male a causare me di perdere un paio di righe nel prima 'metà' dell'output? Ad esempio, dov'è la riga "thread 3 setting threadInt a 84"?
Eseguo il codice un paio di volte e ottengo sempre l'output previsto ... –
Scommetterei che da qualche parte lungo la linea, la chiamata a + = sulla stringa sta ottenendo il valore prima che il thread precedente l'abbia impostata e il nuovo thread lo sta sovrascrivendo con il nuovo valore (quindi il thread 1 ha saltato l'output). – Charleh
@DannyChen Sono su un quad-core e non è l'unico codice in esecuzione nell'applicazione; non so se uno di questi avrebbe senso. Posso caricare l'intero codice da qualche parte (sono solo due file .cs) se lo desideri? – Xenoprimate