2012-02-02 83 views
0

我正在運行Visual Studion 2010(Net 4.0) 我正在創建一個任務,將一些值加載到ObservableCollection中並返回之後的用戶界面。這是代碼:c#tpl,繼續出現問題「調用線程無法訪問對象,因爲不同的線程擁有它」

LoadValues = Task.Factory.StartNew<ObservableCollection<DataGridEntity>>(curDataLoader.LoadValuesTask); 
ItemsList = LoadValues.Result; 
this.DataContext = ItemsList; 

此代碼片段工作正常!但是使用.Result屬性時,UI線程會等待LoadValues任務返回。 所以我想這樣做的:

LoadValues = Task.Factory.StartNew<ObservableCollection<DataGridEntity>>(curDataLoader.LoadValuesTask); 
LoadValues.ContinueWith((FinishLoadDataToDataGrid1) => 
{ 
    ItemsList = LoadValues.Result; 
    this.DataContext = ItemsList; 
}); 

差別很小。我使用了ContinueWith來防止UI線程等待。 但是,如果我這樣做,他告訴我:「調用線程無法訪問對象,因爲不同的線程擁有它」在「this.DataContext = ItemsList;」

它是一個計時問題?有沒有人有任何想法?

回答

4

您需要使用TaskScheduler.FromCurrentSynchronizationContext()在UI線程上運行ContinueWith。

LoadValues = Task.Factory.StartNew<ObservableCollection<DataGridEntity>>(curDataLoader.LoadValuesTask); 
LoadValues.ContinueWith((FinishLoadDataToDataGrid1) => 
{ 
    ItemsList = LoadValues.Result; 
    this.DataContext = ItemsList; 
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 
+0

完美!我不知道爲什麼,但它是帽子。謝謝! – manton 2012-02-02 15:36:24

1

因爲你在UI線程工作,當您使用ContinueWith那麼你的UI繼續UI線程和新的任務執行是在線程池線程執行,當新的任務完成,然後回調函數(這是在傳遞ContinueWith)將在ThreadPool線程上執行。 現在,回調函數嘗試訪問UI線程擁有的對象,並且系統拋出錯誤。

通過調度TaskScheduler.FromCurrentSynchronizationContext()的回調函數,您可以指示系統在UI線程上執行此功能,並且一切正常。

這只是解釋,因爲D.Fihnn已經回答了您的問題。

相關問題