这是怎么回事?从委托内锁定静态对象不起作用
private static object Lock_HandleError = new object();
public static void HandleError(Exception ex)
{
lock(Lock_HandleError)
{
//IF the UI is processing a visual tree event (such as IsVisibleChanged), it throws an exception when showing a MessageBox as described here: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/44962927-006e-4629-9aa3-100357861442
//The solution is to dispatch and queue the MessageBox. We must use BeginInvoke because dispatcher processing is suspended in such cases.
Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate()
{
lock(Lock_HandleError)
{
Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate(){
HandleError(new Exception("testing purposes only"));
}, DispatcherPriority.Background);
MessageBox.Show(ex.Message, "Application Error", MessageBoxButton.OK, MessageBoxImage.Error);
//This point is not reached until the user clicks "OK"
}
}, DispatcherPriority.Background);
}
}
public void main()
{
HandleError(new Exception("The first error"));
}
上述代码的预期的行为是一个错误信息会出现在一个时间,当用户点击“确定”后,在Lock_HandleError
对象将得到派出线程释放,下一调用HandleError可以继续 - 但是我得到的是无限级错误消息,没有打到“OK”。
为什么这个锁不工作?
通过在每个锁定语句的入口和出口处设置断点,我可以清楚地看到代理正在调用lock()
,并再次调用一个新的“HandleError”调用,然后在MessageBox上暂停以等待用户输入。
与此同时,在另一个线程中,调度HandleError的调用得到运行 - 而不是像它应该那样在lock()语句中等待,即使MessageBox委托清楚地放置了一个锁并且还没有发布它。
我对我的多线程不太熟悉,但是我想知道是否可以尝试在'BeginInvoke'方法中删除'lock'? – Richard 2012-03-27 16:07:54
删除锁定并不能完成任何操作 - 因为锁定就像现在不存在一样。虽然UI线程正在等待用户在消息框中单击“确定”,但它会处理来自应用程序其他区域的HandleError()的额外调用,并且我需要它停止并等待。 – Alain 2012-03-27 16:34:50
我试图在这里使用信号量来解决问题:http://stackoverflow.com/questions/9894750/how-can-i-get-the-ui-thread-to-wait-on-a-semaphore-but -process-additional-dispa – Alain 2012-03-27 17:48:54