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;
Другие вопросы по тегам