2014-03-05 64 views
2

不太清楚是怎麼回事 -TaskScheduler.FromCurrentSynchronizationContext例外,從輔助線程調用時

這段代碼導致,因爲它是第一個從主線程調用(在VS任務視圖覈實)問題和調度任務,但是當在UpdateSearchCache中設置斷點時,我們現在處於工作線程中 - 不再是主線程!

從那裏調用的後續UI代碼塊在工作線程上執行時失敗。

是不是指定調度程序的整個點?我錯過了什麼?

啓動我們的應用程序時會調用此代碼。它從我們的PRISM應用程序的引導程序中調用,並在MainThread上運行。

當任務啓動時,SynchronizationContext.Current不爲null。

var currentScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 
var ctx = SynchronizationContext.Current; 
if (ctx == null) 
    throw new NullReferenceException(); 

Task.Factory 
    .StartNew(
     () => 
      SearchHelper.CacheSearchResults(_service.GetData()) 
    .ContinueWith(result => UpdateCache(result.Result), currentScheduler); 
+0

您的代碼片段的第一行是否在主UI線程上執行?如果是這樣,你是否在'Form.Load'等等,這是在'Application.Run'核心循環? – Noseratio

+0

是的,這是主線程。 – cacau

+2

在保存之前,執行以下操作:'Debug.Assert(SynchronizationContext.Current!= null)'。它通過了嗎? – Noseratio

回答

1

TaskScheduler.FromCurrentSynchronizationContext拋出InvalidOperationException當存在調用線程即SynchronizationContext.Current返回null上沒有同步上下文。

+1

但是,當它應該在當前線程a.k.a.main中運行時,如何在工作線程上執行該方法? – cacau

+0

@cacau - 連續計劃的線程取決於您擁有的同步上下文。默認同步上下文計劃要在線程池上運行的任務。但是,如果您遇到異常,則在您開始執行父任務之前就會出現問題,並且此處沒有足夠的代碼來查看可能發生的原因。 – Lee

+0

在我們的應用程序啓動時,我們的(PRISM)引導程序會調用這段被調用的函數。問題編輯相應。至少在VS中我們可以看到一堆工作線程加上當時已經存在的主線程。 – cacau

1

這裏真的很奇怪。嘗試以下方法。這是一種解決方法,但它也可能有助於診斷問題:

var dispatcher = Dispatcher.CurrentDispatcher; 
Debug.Assert(dispatcher == Application.Current.Dispatcher); 

Task.Factory 
    .StartNew(
     () => SearchHelper.CacheSearchResults(_service.GetData())) 
    .ContinueWith(result => 
    { 
     // is the app's dispatcher still the same? 

     Debug.Assert(dispatcher == Application.Current.Dispatcher); 

     // explicitly use Dispatcher.BeginInvoke, that's what 
     // DispatcherSynchronizationContext does behind the scene 

     Application.Current.Dispatcher.BeginInvoke(new Action(
      () => UpdateCache(result.Result))); 

    }, TaskContinuationOptions.ExecuteSynchronously); 
相關問題