2012-02-02 89 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已经回答了您的问题。

相关问题