我正在Visual Studio 2012中的c#wpf中编写一个应用程序。我正在使用mvvm。 我有一个属于UI线程的ObservableCollectionCriteriaCollection,用于从数据库中获取数据我正在使用Task.Factory,因为数据很大并且保存在远程服务器上。 当我点击GetData按钮后执行代码。 我的代码是这样的:
void GetData(object obj)
{
if (CriteriaCollection == null)
CriteriaCollection = new ObservableCollection<Criteria>();
if (SelectedIndex != null && SelectedCriteria != null)
{
bool results = this.CriteriaCollection.Any(report =>
report.CriteriaName.Equals(
this.SelectedCriteria.CriteriaName.ToString()));
if (!results)
{
Task.Factory.StartNew(() =>
{
IsBusy = true;
Criteria newCriteria = new Criteria();
ExecuteGetDataFromDB(null);
///some code which populates values and fills newCriteria
CriteriaCollection.Add(newCriteria);
}).ContinueWith(result =>
{
IsBusy = false;
});
}
}
}
我在CriteriaCollection.Add(newCriteria)行获得了一个例外;说This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
有人可以帮我吗?
谢谢!
答案 0 :(得分:2)
GUI相关代码只能从GUI线程或另一个线程的调度程序执行:
Application.Current.Dispatcher.Invoke(new Action(() =>
{
// your GUI related code here
}));
答案 1 :(得分:0)
创建任务以执行后台工作的代码不太正确,我相信你想要更像这样的东西:
IsBusy = true;
Task<SomeResult>.Factory.StartNew(() =>
{
Criteria newCriteria = new Criteria();
return ExecuteGetDataFromDB(newCriteria);
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default)
.ContinueWith(t =>
{
CriteriaCollection.Add(t.Result);
IsBusy = false;
}, TaskScheduler.FromCurrentSynchronizationContext());
这样做是在后台线程上创建任务,当它在UI线程上完成'继续'时,希望你不再得到例外。
请注意,您必须将SomeResult
类定义为ExecuteGetDataFromDB
方法的返回类型。