2012-10-04 63 views
23

我試圖在Windows 8中再次嘗試/取消對話框。對話框第一次顯示罰款,但再次單擊再次嘗試失敗,我得到一個拒絕訪問在調用ShowAsync。 我不知道爲什麼,但它奇怪的有時代碼工作正常,我沒有得到例外,當我把斷點。這裏真的很無知MessageDialog ShowAsync在第二個對話框上拋出訪問異常

這裏是代碼。

async void DismissedEventHandler(SplashScreen sender, object e) 
    { 
     dismissed = true; 
     loadFeeds(); 
    } 
    private async void loadFeeds() 
    { 
     await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => 
     { 
      try 
      { 
       RSSDataSource rssDataSource = (RSSDataSource)App.Current.Resources["RSSDataSource"]; 
       if (rssDataSource != null) 
       { 
        await rssDataSource.DownloadFeeds(); 
        await rssDataSource.GetFeedsAsync(); 
       } 

       AdDataSource ads = (AdDataSource)App.Current.Resources["AdDataSource"]; 

       if (ads != null) 
       { 
        await ads.DownloadAds(); 
       } 
       rootFrame.Navigate(typeof(HomePageView)); 

       Window.Current.Content = rootFrame; 
      } 
      catch 
      { 
       ShowError(); 
      } 

     }); 
    } 
    async void ShowError() 
    { 
     // There was likely a problem initializing 
     MessageDialog msg = new MessageDialog(CONNECTION_ERROR_MESSAGE, CONNECTION_ERROR_TITLE); 

     // Add buttons and set their command handlers 
     msg.Commands.Add(new UICommand(COMMAND_LABEL_RETRY, new UICommandInvokedHandler(this.CommandInvokedHandler))); 
     msg.Commands.Add(new UICommand(COMMAND_LABEL_CLOSE, new UICommandInvokedHandler(this.CommandInvokedHandler))); 
     // Set the command to be invoked when a user presses 'ESC' 
     msg.CancelCommandIndex = 0; 

     await msg.ShowAsync(); 
    } 

    /// <summary> 
    /// Callback function for the invocation of the dialog commands 
    /// </summary> 
    /// <param name="command">The command that was invoked</param> 
    private void CommandInvokedHandler(IUICommand command) 
    { 
     string buttonLabel = command.Label; 
     if (buttonLabel.Equals(COMMAND_LABEL_RETRY)) 
     { 
      loadFeeds(); 
     } 
     else 
     { 
      // Close app 
      Application.Current.Exit(); 
     } 
    } 

回答

24

好,我發現了一個快速的解決方案,

限定IAsyncOperation類varialble

IAsyncOperation<IUICommand> asyncCommand = null; 

並將其設置爲MessageDialog

asyncCommand = msg.ShowAsync(); 

的ShowAsync方法在命令處理程序重試/再試一次 檢查asyncCommand是否不是null並取消最後的操作,如有必要

if(asyncCommand != null) 
{ 
    asyncCommand.Cancel(); 
} 

請讓我,如果有更好的方法來做到這一點。

+0

要預防 「未分配的局部變量 'asyncCommand' 的使用」,我不得不分配分配給asyncCommand時爲null。 –

+1

備註:我有自己的任務隊列在一個線程中運行,我一次只能從一個線程執行一個ShowAsync。顯然,如果一個ShowAsync在第一幀中結束,第二個ShowAsync在第二幀中開始,隨機訪問拒絕錯誤可以彈出:/。儘管手動取消作品。 – RelativeGames

+0

@clay我更新了上面的代碼 – Syler

3

在MSDN論壇上有一個可以幫助你的答案。

http://social.msdn.microsoft.com/Forums/en-US/winappswithhtml5/thread/c2f5ed68-aac7-42d3-bd59-dbf2673dd89b

我有一個類似的問題,但我的showAsync通話是在單獨的線程上不同的功能,所以我不能降一完成()在那裏,我不認爲......

+1

嘗試使用實例變量並保存對asyncCommand的引用,並檢查命令是否爲空。它可能工作。 – Syler

+1

是的,在我的情況下工作。雖然 –

3

我幾天前面對同樣的問題,我解決它等待ShowAsync,然後再次進行遞歸調用,打開MessageDialog。

public async void ShowDlg(){ 
    Action cmdAction = null; 
    var msgDlg = new MessageDialog("Content.", "Title"); 
    msgDlg.Commands.Add(new UICommand("Retry", (x) => { 
    cmdAction =() => ShowDlg(); 
    })); 
    msgDlg.Commands.Add(new UICommand("Cancel", (x) => { 
    cmdAction =() => <Action associated with the cancel button>; 
    })); 
    msgDlg.DefaultCommandIndex = 0; 
    msgDlg.CancelCommandIndex = 1; 

    await msgDlg.ShowAsync(); 
    cmdAction.Invoke(); 
} 

希望得到這個幫助!

9

我遲到了,但這裏有一個方法,你可以隨時聽候對話框的結果,以及不需要擔心調用連續太多:

首先定義一個靜態變量和方法在您的應用程序中:

private static IAsyncOperation<IUICommand> messageDialogCommand = null; 
public async static Task<bool> ShowDialog(MessageDialog dlg) { 

    // Close the previous one out 
    if (messageDialogCommand != null) { 
     messageDialogCommand.Cancel(); 
     messageDialogCommand = null; 
    } 

    messageDialogCommand = dlg.ShowAsync(); 
    await messageDialogCommand; 
    return true; 
} 

現在,您可以傳入任何對話框並始終等待執行。這就是爲什麼這返回一個布爾而不是無效。您不必擔心倍數之間的衝突。爲什麼不讓這個方法接受一個字符串?由於標題和Yes/No命令處理程序,您可以將其分配到您正在使用的特定對話框中。

調用如:

await App.ShowDialog(new MessageDialog("FOO!")); 

var dlg = new MessageDialog("FOO?", "BAR?"); 
dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(YesHandler))); 
dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler(NoHandler))); 
await App.ShowDialog(dlg); 
2

另一種解決方案:

private bool _messageShowing = false; 

// ... 

if (!_messageShowing) 
{ 
    _messageShowing = true; 
    var messageDialog = new MessageDialog("Example"); 

    // ... "messageDialog" initialization 

    Task<IUICommand> showMessageTask = messageDialog.ShowAsync().AsTask(); 
    await showMessageTask.ContinueWith((showAsyncResult) => 
     { 
      _messageShowing = false; 
     }); 
} 
+0

Thx似乎大量hacky!這是唯一的解決方案,適合我! –

相關問題