【发布时间】:2012-03-27 16:02:53
【问题描述】:
这怎么行不通?
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 语句的入口和出口处设置断点,我可以清楚地看到委托正在调用 lock() 并再次调度对“HandleError”的新调用,然后在 MessageBox 上暂停以等待用户输入。
同时,在另一个线程中,对 HandleError 的分派调用开始运行 - 但不是像应有的那样等待 lock() 语句,它只是通过它爆炸,即使 MessageBox 委托明确放置了一个锁并且尚未释放它。
【问题讨论】:
-
我在多线程方面还不够,但我想知道您是否可以尝试在
BeginInvoke方法中删除lock? -
移除锁不会完成任何事情 - 因为锁的行为就像它甚至不存在一样。当 UI 线程等待用户在消息框上单击“确定”时,它会处理来自应用程序其他区域的对 HandleError() 的额外调用,我需要它停止并等待。
-
我尝试在这里使用信号量解决问题:stackoverflow.com/questions/9894750/…