2013-06-24 116 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