2013-12-16 1 views
1

WinRT 응용 프로그램에서 UI를 사용하면 사용자가 목록 항목을 클릭하여 서버에서 미리보기를 다운로드 할 수 있습니다. 목록 항목이이 다운로드 상태에 있으면 진행률 표시 줄이 목록 항목 템플리트에 표시됩니다. 따라서 UI는 차단되지 않으며 사용자는 자유롭게 다른 항목을 클릭하고 해당 항목을 (동시) 다운로드를 시작할 수 있습니다.대기중인 작업을 FIFO 순서로 serialize하는 방법

다운로드가 실패하면 (네트워크 연결로 인해), UI에 메시지를 보냅니다. 인터페이스는 MessageDialog를 표시함으로써이 메시지를 처리한다 :

public async void ShowError(string message) 
{ 
    var dialog = new MessageDialog(message, "Error") 
    { 
     CancelCommandIndex = 0, 
     DefaultCommandIndex = 0, 
     Options = MessageDialogOptions.None 
    }; 
    dialog.Commands.Add(new UICommand("OK")); 

    await dialog.ShowAsync(); 
} 

문제는 상기 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 스레드입니까?

누구나 올바른 방향으로 나를 가리킬 수 있습니까? 이미 이것을 쓰고 있기 때문에, 난 당신을 제안, 그러나

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(); 
    } 
} 

: 내가 원하는 무엇

답변

3

는 가장 쉬운 솔루션은 SemaphoreSlim 인이

에 대한 액세스를 직렬화입니다 이 부분을 다시 생각해보십시오 :

다운로드가 실패하면 (네트워크 연결로 인해) 가정 해 봅니다. UI에 대한 메시지를 종료합니다. UI가이 메시지를 처리합니다 ...

UI를 전혀 알지 못하는 백그라운드 작업이있는 경우 코드가 훨씬 더 깨끗합니다. 메시지 버스를 사용하는 경우 괜찮습니다 (메시지 버스가 필요한 UI 앱에서는 작업 한 적이 없지만). 하지만 UI에 직접 메시지를 보내는 백그라운드 작업은 피하고 싶습니다.

+0

구조화 된 방법은 ViewModel에 선택된 목록 항목에 대한 미리보기를 다운로드 할 수있는 방법이 있다는 것입니다. 이 메서드는 비동기식이므로 UI ​​스레드는 즉시 반환되어 사용자가 다른 목록 항목을 선택하고 동시 다운로드를 시작할 수 있습니다. 주어진 다운로드가 실패 (캐치 예외)되면 우리는 뷰가 구독하는 뷰 모델로부터 메시지를 보냅니다. 뷰는 오류 메시지 대화 상자를 표시하여이 메소드를 처리합니다. –

+0

이것은보기에는 좋아 보이지만 실제로는 제대로 작동하지 않았습니다. 그 결과는 ... 이상하지만 ... 두 번째 메시지 상자가 나타나 자마자 UI가 업데이트를 중단 한 것처럼 보였습니다. 업데이트는 중단되었지만 여전히 클릭에 반응했습니다. 비동기가있는 배관 공사 일 수도 있고 이해가 안 될 수도 있습니다. –

관련 문제