Задача MessageDialog не отображается, если я использую Task.Wait() вместо ожидания

Я не знаю разницы между ожиданием задачи и использованием task.Wait(), но для метода MessageDialog.ShowAsync с первым он работает, но не со вторым (в то время как два синтаксиса работают с другими асинхронными методами).

Если кто-нибудь может объяснить, почему мне будет интересно!

// this don't work, no dialog is shown (and UI is block)
var dialog = new MessageDialog("fail");
var task = dialog.ShowAsync().AsTask();
task.Wait();

// this work
var dialog = new MessageDialog("success");
var task = dialog.ShowAsync().AsTask();
await task;

Вы спросите меня, почему я хочу это сделать, потому что мне нужно показать диалоговое окно в блоке catch (чтобы показать сообщение об ошибке) и дождаться, пока пользователь закроет диалоговое окно, прежде чем продолжить после блока catch (и да, мы можем не используйте await в блоке catch, но мы можем использовать Task.Wait(), я успешно использовал его с другими асинхронными методами).


person Thomas Laurent    schedule 24.06.2012    source источник


Ответы (2)


Отображение диалогового окна (и реагирование на нажатие кнопки в нем) должно выполняться из потока пользовательского интерфейса. Но если вы вызываете Wait() в потоке пользовательского интерфейса, вы в основном говорите, что ничего больше не может произойти в этом потоке, пока не завершится Task. Вот почему диалоговое окно не может быть показано, и поэтому ваше приложение зависает.

Таким образом, поток пользовательского интерфейса ожидает диалогового окна, а диалоговое окно ожидает потока пользовательского интерфейса, что является классическим . тупик. Я считаю, что использование Wait() в потоке пользовательского интерфейса является наиболее распространенной причиной взаимоблокировок в приложениях с графическим интерфейсом C # 5.

person svick    schedule 24.06.2012
comment
Отличное наблюдение - учитывая эффект уничтожения способности обрабатывать дальнейшие сообщения, мне интересно, может ли вызов Wait() в потоке пользовательского интерфейса быть чем-то, что можно было бы обнаружить и вызвать бросок (так же, как попытка записи в компоненты пользовательского интерфейса из неправильного потока делает), чтобы улучшить опыт разработчика (поскольку «замороженное приложение» не очень действенное/отлаживаемое состояние :) - person James Manning; 24.06.2012
comment
Конечно, слишком поздно для 2012 года, но все равно подал заявку — -ui-thread-or-relevant-thread-for-other-sync-contexts-should-throw" rel="nofollow noreferrer">connect.microsoft.com/VisualStudio/feedback/details/750636/ - person James Manning; 24.06.2012
comment
@JamesManning Не думаю, что это хорошая идея. Wait()ing на чем-то, что не использует поток пользовательского интерфейса, является вполне допустимым подходом (хотя, возможно, не очень удобным для пользователя из-за временного зависания), особенно в коде C# 4. - person svick; 24.06.2012
comment
извините, что не разъяснил - Wait() из потока пользовательского интерфейса, когда задача, которую вы ожидаете, имеет контекст синхронизации, говорит, что она должна выполняться в потоке пользовательского интерфейса. Конечно, он мог (и мог, я забыл) просто запустить задачу в таком сценарии. - person James Manning; 25.06.2012

task.Wait() блокируется до тех пор, пока задача не будет завершена, а await продолжает обработку. Я предполагаю, что, поскольку пользовательский интерфейс заблокирован, диалоговое окно сообщения не может появиться.

person Chris Gessler    schedule 24.06.2012