2013-07-23 57 views
4

由於捕獲異常而顯示消息對話框的正確方法是什麼?由於捕獲的異常而顯示WinRT MessageDialog的正確方法是什麼?

我最初試圖

try 
{ 
    await DoSomething(); 
} 
catch(InvalidOperation ex) 
{ 
    await MessageDialog(ex.Message).ShowAsync(); 
} 
catch(CommunicationException) 
{ 
    await MessageDialog(StringResourceLoader.LoginError).ShowAsync(); 
} 

這並沒有工作,因爲你不能await try塊內。編譯器顯示以下警告:

由於未調用此調用,因此在調用完成之前繼續執行當前方法。考慮應用「等待」運營商的呼叫

我不喜歡保持這些警告在我的代碼的結果,因爲在幾個景點的人已經忘記了使用await因此具有難以發現漏洞。

更改消息對話框語句var task = new MessageDialog(ex.Message).ShowAsync().AsTask();擺脫所有的警告和錯誤的,但我不知道那是去了解它的好方法(和技術上是壞它要我await調用同樣的原因)

最後,我想存儲異常,並做我的東西顯示給用戶邏輯(包括所有邏輯上確定被拋出異常的類型)漁獲量之外,通過:

Exception thrownException = null; 
try 
{ 
    await DoSomething(); 
} 
catch(Exception ex) 
{ 
    thrownException = ex; 
} 

if (thrownException is InvalidOperationException) 
    await MessageDialog(ex.Message).ShowAsync(); 
else if (thrownException is CommunicationException) 
    await MessageDialog(StringResourceLoader.LoginError).ShowAsync(); 

我我不確定我是否覺得這是最好的方法。任何想法如何做到這一點?

+2

這裏有多個問題,當你的應用程序已經顯示一個時,MessageDialog也會變得非常暴躁。換句話說,你永遠不能確定用戶會真正看到它。最有可能的結果是一個無法察覺的原因炸到桌面的應用程序。 真正解決這個問題需要一個接一個顯示消息的隊列。或者換句話說,在消息對話框中顯示異常並不是一個好主意。 –

+0

這是一個好點,並有一個有趣的想法有一個隊列... – KallDrexx

+0

請務必檢查類似的問題[這裏](http://stackoverflow.com/questions/14488587/how-to-allow-for-multiple -popups-AT-一次在WinRT中)。 –

回答

4

編輯: 後漢斯其他問題的評論,我結束了創建以下類解決它:

public static class MessageDialogDisplayer 
{ 
    private static readonly ConcurrentQueue<MessageDialog> _dialogQueue; 
    private static readonly CancellationTokenSource _cancellationTokenSource; 

    static MessageDialogDisplayer() 
    { 
     _dialogQueue = new ConcurrentQueue<MessageDialog>(); 
     _cancellationTokenSource = new CancellationTokenSource(); 

     new Task(DisplayQueuedDialogs, _cancellationTokenSource.Token).Start(); 
    } 

    public static void DisplayDialog(MessageDialog dialog) 
    { 
     _dialogQueue.Enqueue(dialog); 
    } 

    private static async void DisplayQueuedDialogs() 
    { 
     const int millisecondsBetweenDialogChecks = 500; 

     while (!_cancellationTokenSource.Token.IsCancellationRequested) 
     { 
      MessageDialog dialogToDisplay; 
      if (_dialogQueue.TryDequeue(out dialogToDisplay)) 
      { 
       await dialogToDisplay.ShowAsync(); 
      } 
      else 
      { 
       await Task.Delay(millisecondsBetweenDialogChecks); 
      } 
     } 
    } 
} 

這改變了我的try/catch語句

MessageDialog errorDialog = null; 
try 
{ 
    await DoSomething(); 
} 
catch(InvalidOperation ex) 
{ 
    MessageDialogDisplayer.DisplayDialog(new MessageDialog(ex.Message)); 
} 
catch(CommunicationException) 
{ 
    MessageDialogDisplayer.DisplayDialog(new MessageDialog(StringResourceLoader.LoginError)); 
} 

從長遠來看,這使得事情更加穩定(一旦我將所有消息對話框調用者轉換爲使用它而不是自己的showAsyncing),並使try/catch塊更不混亂(imo )。

+0

嗨,這真的是解決這個問題的最好方法嗎?據我所知,MessageDialogDisplayer創建一個始終運行的Task,每半秒檢查一次消息?當任務被取消時,我們不能顯示任何其他消息,因爲while循環停止。這是否有效(因爲你寫這篇文章已經快一年了)? –

+1

雖然我不再爲這家公司工作,但據我所知,這仍然工作*足夠好*。我不認爲取消是一個問題,因爲老實說,我看不出任何你想要明確取消對話跑步者的理由(實際上沒有辦法這樣做,所以它沒有任何意義)。我相信可能會有更好的解決方案,但最終我們只需要這樣做就只顯示錯誤,所以沒有用於其他用例的過度工程設計。 – KallDrexx

相關問題