2013-12-16 31 views
1

在我的WinRT應用程序中,用戶界面允許用戶單擊列表項以開始從服務器下載預覽。當列表項目處於此下載狀態時,列表項目模板中將顯示一個進度條。因此,用戶界面不會被阻止,用戶可以自由地點擊其他項目並開始(併發)下載。我怎樣才能按照FIFO順序序列化等待任務

當下載失敗時(由於網絡連接,比方說),它發送消息到用戶界面。用戶界面通過顯示MessageDialog處理此消息:

​​

的問題是,如果UI嘗試用戶已經駁回第一之前顯示的另一消息,所述呼叫到MessageDialog.ShowAsync拋出System.UnauthorizedAccessException

我想要做的就是對此進行序列化訪問,以便第二條消息等待第一條消息,然後顯示。第三條消息將等待第二條消息,以此類推。

所有這一切都發生在UI線程上,我不知道如何正確執行此操作。好像我希望每個新的錯誤消息框,要求將自己設置爲「當前」的請求,然後等待的「以前」一個被解僱:

public async void ShowError(string message) 
{ 
    ... 

    // *** PSEUDO CODE FOLLOWS *** 

    // If a message is being displayed... 
    if (_currentTask != null) 
    { 
     // ...wait for that task to complete 
     _currentTask = NewTaskThatWaitsFor(_currentTask); 
     await _currentTask; 
    } 
    _currentTask = dialog.ShowAsync(); 
    await currentTask; 
} 

我怎樣才能「附掛」我等待(不是阻止 - 這是UI線程)在我以前等待的另一個(UI線程)任務上?

任何人都可以指向正確的方向嗎?

回答

3

我想要做的是串行訪問這個

最簡單的解決方案是一個SemaphoreSlim

private readonly SemaphoreSlim _dialogMutex = new SemaphoreSlim(1); 
public async void ShowError(string message) 
{ 
    await _dialogMutex.WaitAsync(); 
    try 
    { 
     var dialog = new MessageDialog(message, "Error") 
     { 
      CancelCommandIndex = 0, 
      DefaultCommandIndex = 0, 
      Options = MessageDialogOptions.None 
     }; 
     dialog.Commands.Add(new UICommand("OK")); 

     await dialog.ShowAsync(); 
    } 
    finally 
    { 
     _dialogMutex.Release(); 
    } 
} 

但是,因爲我已經寫這件事,我建議你重新考慮這部分:

當下載失敗(由於網絡連接,讓我們說),它s結束消息到用戶界面。用戶界面處理此消息...

我發現如果您的後臺任務完全不知道用戶界面,代碼會更乾淨。如果你使用的是消息總線,那很好(雖然我從來沒有在需要消息總線的UI應用上工作過);但是你想避免的是直接向UI發送消息的後臺任務。

+0

它的結構方式是在ViewModel中有一個可供選擇的方法,用於下載所選列表項目的預覽。由於該方法是異步的,UI線程立即返回,允許用戶選擇其他列表項並開始併發下載。當給定的下載失敗(捕獲異常)時,我們從視圖模型發送視圖訂閱的消息。該視圖通過顯示錯誤消息對話框來處理此方法。 –

+0

這看起來不錯,但它在實踐中並不完全適用於我。結果是......很奇怪......,但是就像第二個消息框彈出後UI停止更新一樣。停止更新,但仍然響應點擊。必須與異步/等待,我不明白的一些管道事情。 –

相關問題