Tenir compte de l'extrait de test suivant:Comment puis-je garantir un résultat déterministe pour ce problème de multithreading?
// act
AutoResetEvent workDoneEvent = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(delegate
{
ProcessAndSignal(processor, workDoneEvent);
}, null);
// let worker thread have a go
workDoneEvent.WaitOne();
blockingFetcher.WaitForNextMessage = false;
// assert
Assert.That(processor.StopCause, Is.Null);
}
private static void ProcessAndSignal(MessageProcessor processor, AutoResetEvent workDoneEvent)
{
workDoneEvent.Set();
// this invocation will block until the WaitForNextMessageFlag is set
processor.ProcessMessages();
}
scénario idéal:
- ProcessAndSignalMethod est mis en attente sur le pool de threads, mais ne démarre pas à exécuter.
- Les principaux blocs de filetage (autoResetEvent.WaitOne())
- Un thread de travail commence à exécuter le procédé « ProcessAndSignal »
- Les threads de travail a suffisamment de temps pour signaler le drapeau et lancer l'exécution de la méthode ProcessMessages
- Le thread principal est réinjecté dans la vie et définit la propriété qui provoquera l'achèvement de la méthode ProcessAndSignal
Le scénario suivant peut-il se produire?
1) ProcessAndSignal() commencera à exécuter avant le thread principal définit le AutoResetEvent à WaitOne() qui provoquera un blocage (les processor.ProcessMessages() va entrer dans une boucle de infinitif)