我正在运行Visual Studion 2010(Net 4.0)我正在创建一个任务,将一些值加载到ObservableCollection中,然后返回UI。这是代码:
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;"
这是时间问题吗?有人有什么想法吗?
您需要使用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());
因为您在UI线程上工作,当您使用ContinueWith时,您的UI将继续在UI线程中执行,新任务将在ThreadPool线程上执行,当新任务完成时,回调函数(在ContinueWith中传递)将在ThreadPool线程上执行。现在回调函数试图访问UI线程拥有的对象,系统抛出错误。
通过在TaskScheduler.FromCurrentSynchronizationContext()上调度回调函数,您可以指导系统在UI线程上执行此函数,一切正常。
这只是解释,因为D.费恩已经回答了你的问题。