MessageDialog - нужно ждать ввода пользователя
У меня есть ViewModel, который создает событие в синхронном методе. Событие сигнализирует пользовательскому интерфейсу, что перед тем, как продолжить, нам нужен ответ "Да" или "Нет" от пользователя.
Я пытаюсь отобразить MessageDialog
и дождитесь ответа пользователя - да или нет. Мне трудно это сделать. Я в настоящее время получаю UnauthorizedAccessException
при попытке сделать это.
Вот посмотрите на код в пользовательском интерфейсе:
async Task<bool> Instance_SwitchConfirmation(string question)
{
MessageDialog md = new MessageDialog(question);
md.Commands.Add(new UICommand("Yes", CommandInvokedHandler));
md.Commands.Add(new UICommand("No", CommandInvokedHandler));
md.ShowAsync();
return this.canSwitch;
}
async void CommandInvokedHandler(IUICommand command)
{
this.canSwitch = command.Label == "Yes" ? true : false;
}
Я пытался:
var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() => {
MessageDialog md = new MessageDialog(question);
md.Commands.Add(new UICommand("Yes", CommandInvokedHandler));
md.Commands.Add(new UICommand("No", CommandInvokedHandler));
md.ShowAsync();
},
new System.Threading.CancellationToken(),
TaskCreationOptions.PreferFairness, uiContext);
но это не с тем же исключением.
Наконец, если я просто так жду MessageDialog, диалоговое окно не отображается, и поток пользовательского интерфейса блокируется.
MessageDialog md = new MessageDialog(question);
md.Commands.Add(new UICommand("Yes", CommandInvokedHandler));
md.Commands.Add(new UICommand("No", CommandInvokedHandler));
await md.ShowAsync();
Если MessageDialog
была синхронная версия Show()
Я был бы в порядке, но асинхронный бевейер MessageDialog
в сочетании с моей синхронной рутиной, в сочетании с перекрестными потоками сбивает меня с толку. Мне интересно, если кто-то может обрисовать в общих чертах, что мне нужно сделать, чтобы ждать ввода пользователя на MessageDialog
прежде чем продолжить синхронный метод в моем бэкэнде ViewModel.
Заранее спасибо за помощь.
1 ответ
См. Диспетчер Win8 C# Metro и RPC_E_WRONG_THREAD и CoreDispatcher.RunAsync
,
Так как ваш метод не выполняется на Dispatcher
вам нужно будет вызвать код на нем вручную. Чтобы избежать рефакторинга в шаблон обратного вызова, вы можете использовать TaskCompletionSource(T)
установить результат, и фоновый поток продолжится после того, как результат будет установлен.
var tcs = new TaskCompletionSource<bool>();
var dialogTask = tcs.Task;
MessageDialog md = new MessageDialog(question);
md.Commands.Add(new UICommand("Yes"));
md.Commands.Add(new UICommand("No"));
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => {
var result = await md.ShowAsync();
var canSwitch = result.Label == "Yes";
tcs.SetResult(canSwitch);
});
var result = await dialogTask;
return result;