2013-06-24 75 views
2

我有一个ViewModel在同步方法中实例化一个事件。事件向用户界面发出信号,告知用户在继续之前需要“是”或“否”答案。MessageDialog - 需要等待用户输入

我正在尝试显示一个MessageDialog,并等待用户提供答案 - 是或否我正在很难做到这一点。试图这样做时,我目前得到一个UnauthorizedAccessException

下面就来看看在UI代码:

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,则不显示对话框并且UI线程锁定。

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加上我synchrounous常规的asynchrnous behvaior,加上跨线程是混淆了我。我想知道是否有人能够在我的后端ViewModel中继续同步方法之前概述我需要做什么来等待用户输入MessageDialog

在此先感谢您的帮助。

回答

7

请参阅Win8 C# Metro dispatcher and RPC_E_WRONG_THREADCoreDispatcher.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; 
+0

感谢您的回复,但我需要等待用户输入,然后才能继续执行代码。如果我等待Dispather.RunAsync调用,则不显示MessageDialog,并且UI线程锁定。有什么建议么?提前致谢。 – user2334154

+0

这可能是因为回调。试试我的编辑。 – Romoku

+0

再次感谢您的快速响应。不幸的是,这仍然是不等待,我有一个回报canSwitch;这个调用之后的语句以及它在显示MessageDialog之前被调用,如果我等待Dispatcher.RunAsync调用,我再次锁定了UI线程。任何其他想法? – user2334154