c# tpl, continuewith 的问题“调用线程无法访问对象,因为不同的线程拥有它”

man*_*ton 0 visual-studio-2010 task-parallel-library

我正在运行 Visual Studion 2010 (Net 4.0),我正在创建一个任务,将一些值加载到 ObservableCollection 中,然后返回到 UI。这是代码:

LoadValues = Task.Factory.StartNew<ObservableCollection<DataGridEntity>>(curDataLoader.LoadValuesTask);
ItemsList = LoadValues.Result;
this.DataContext = ItemsList;
Run Code Online (Sandbox Code Playgroud)

这段代码运行得很好!但使用 .Result 属性,UI 线程会等待,直到 LoadValues 任务返回。所以我想这样做:

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

差别很小。我使用ContinueWith 来防止UI 线程等待。但如果我这样做,他告诉我:“调用线程无法访问对象,因为不同的线程拥有它”在“this.DataContext = ItemsList;”

是不是时间问题?有人有什么想法吗?

D.F*_*hnn 5

您需要使用 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());
Run Code Online (Sandbox Code Playgroud)