请考虑以下测试代码段:
// 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();
}
理想情景:
是否会出现以下情况?
1)ProcessAndSignal()将在主线程将AutoResetEvent设置为WaitOne()之前开始执行,这将导致死锁(processor.ProcessMessages()将进入不定式循环)
答案 0 :(得分:1)
是的,可能会出现这种情况。是的,如果你没有将bool变量声明为volatile,它就会死锁。只是不要使用bool,使用像你一样的事件。
逻辑看起来很奇怪,它闻起来就像你试图让主线程等待处理完成。 workDoneEvent实际上并不表示工作已完成。现在主线程将在工作完成之前检查断言,这可能不太好。如果意图是它表示工作者已完成,那么ProcessAndSignal应该是在方法结束时调用Set()的那个。主线程应该调用WaitOne()。
如果这完全准确,那么你就不应该使用QUWI,只需直接调用ProcessAndSignal而不使用线程。 远更高效,线程问题零赔率。