2013-07-10 38 views
0

我使用Caliburn Micro的協同工作程序來顯示WPF中的屏幕。Caliburn Micro - 協程 - UI線程意外阻塞

我爲繁忙的屏幕製作了這個IDisposable構造:圍繞長時間運行的作業使用using語句,並在該作業期間顯示繁忙的屏幕。當使用塊結束時,Dispose()將隱藏幕後的繁忙屏幕。

的使用範圍的建設顯示和隱藏使用繁忙的屏幕..

Application.Current.Dispatcher.Invoke(...show/hide form...) 

。要做到這一點的UI線程:

的用法的例子:

yield return new TaskResult(Task.Factory.StartNew(() => 
{ 
    using (_dialogController.ShowDialogForUsingScope(new BusyViewModel() 
         { Message = "Account gegevens ophalen..." })) 
    { 
    _securityContext.RefreshAccountFromServer(); 
    } 
    using (_dialogController.ShowDialogForUsingScope(new BusyViewModel() 
         { Message = "You see me..." })) 
    { 
    _securityContext.RefreshAccountFromServer(); 
    } 
})); 

這很好地工作:繁忙的屏幕顯示,工作完成,它被刪除,緊接着第二個工作期間另一個繁忙的屏幕,然後完成:)

但是當我2產量做它返回的第二份工作是在UI線程上如果想運行:導致

Debug.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId + ", IsBackground: " + Thread.CurrentThread.IsBackground); 
yield return new TaskResult(Task.Factory.StartNew(() => 
{ 
    Debug.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId + ", IsBackground: " + Thread.CurrentThread.IsBackground); 
    using (_dialogController.ShowDialogForUsingScope(new BusyViewModel() { Message = "Account gegevens ophalen..." }, 2000)) 
    { 
     _securityContext.RefreshAccountFromServer(); 
    } 
})); 
Debug.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId + ", IsBackground: " + Thread.CurrentThread.IsBackground); 
yield return new TaskResult(Task.Factory.StartNew(() => 
{ 
    Debug.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId + ", IsBackground: " + Thread.CurrentThread.IsBackground); 
    using (_dialogController.ShowDialogForUsingScope(new BusyViewModel() { Message = "You never see me..." }, 2000)) 
    { 
    } 
})); 

Thread: 9, IsBackground: False 
Thread: 12, IsBackground: True 
Thread: 9, IsBackground: False 
Thread: 9, IsBackground: False --> 9 too ?? 

這就解釋了爲什麼它凍結,但爲什麼是任務不在另一個線程上?

+0

就像一張紙條,標籤未來有關Caliburn.Micro與caliburn.micro標籤的問題,因爲舊的框架不再被維護。 –

+0

謝謝,我知道這一點,但不知道如何輸入Caliburn Micro作爲標籤,但它是與一個點:) – Thomas

回答

2

google搜索了很多之後,我發現這個完整的答案:

Is Task.Factory.StartNew() guaranteed to use another thread than the calling thread?

看來任務調度是誘惑,運行在請求的線程(任務在UI線程是同步的一些情況我的情況)。

爲了防止這種情況,你需要通過默認的調度啓動任務時,而不是現在的(這是默認行爲):

例子:

yield return new TaskResult(Task.Factory.StartNew(() => 
      { 
       using (_dialogController.ShowDialogForUsingScope(new BusyViewModel() { Message = "Inloggen..." }, 800)) 
       { 
        // do stuff 
       } 
      }, 
      CancellationToken.None, 
      TaskCreationOptions.None, 
      TaskScheduler.Default));