Почему это не работает?Заблокировать статический объект из делегата не работает
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"));
}
Ожидаемое поведение выше кода является то, что один появится сообщение об ошибке, в то время, и когда пользователь нажимает кнопку «OK», то на Lock_HandleError
объект освобождается от блокировки от посланной нити, а следующий вызов HandleError может продолжаться - но то, что я получаю, - это бесконечный каскад сообщений об ошибках, даже не нажимая «ОК».
Почему этот замок не работает?
Установив точки останова при вводе и выходе из каждого оператора блокировки, я ясно вижу, что делегат вызывает lock()
и снова отправляет новый вызов в «HandleError», а затем приостанавливает работу MessageBox, ожидая ввода пользователя.
Между тем, в другом потоке этот вызов HandleError запускается, но вместо ожидания в операторе lock(), как и следовало ожидать, он просто взрывается через него, хотя делегат MessageBox явно размещает блокировку и еще не успел выпустил его.
Я не могу поцарапать свою многопоточность, но мне интересно, можно ли попытаться удалить «блокировку» в методе «BeginInvoke»? – Richard
Удаление замка ничего не может сделать, потому что замок действует так, как будто он даже не существует. Пока поток пользовательского интерфейса ожидает, чтобы пользователь нажал «ОК» в окне сообщения, он обрабатывает дополнительные вызовы HandleError(), поступающие из других областей приложения, и мне нужно его остановить и подождать. – Alain
Я попытался решить проблему с помощью семафоров здесь: http://stackoverflow.com/questions/9894750/how-can-i-get-the-ui-thread-to-wait-on-a-semaphore-but -process-extra-dispa – Alain