C# 从工作线程访问UI线程集合
我正在Visual studio 2012中用c#wpf编写一个应用程序。我正在使用mvvm。 我有一个属于UI线程的ObservaleCollectionCriteriaCollection,用于从数据库中获取数据,我使用Task.Factory,因为数据很大,保存在远程服务器上。 当我点击GetData按钮时,执行以下代码。 我的代码如下:C# 从工作线程访问UI线程集合,c#,wpf,multithreading,mvvm,C#,Wpf,Multithreading,Mvvm,我正在Visual studio 2012中用c#wpf编写一个应用程序。我正在使用mvvm。 我有一个属于UI线程的ObservaleCollectionCriteriaCollection,用于从数据库中获取数据,我使用Task.Factory,因为数据很大,保存在远程服务器上。 当我点击GetData按钮时,执行以下代码。 我的代码如下: void GetData(object obj) { if (CriteriaCollection == null)
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;
});
}
}
}
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());
void GetData(对象obj)
{
if(CriteriaCollection==null)
CriteriaCollection=新的ObservableCollection();
if(SelectedIndex!=null&&selectedCriterias!=null)
{
bool results=this.CriteriaCollection.Any(报告=>
report.CriteriaName.Equals(
this.SelectedCriteria.CriteriaName.ToString());
如果(!结果)
{
Task.Factory.StartNew(()=>
{
IsBusy=true;
Criteria newCriteria=新标准();
ExecuteTDataFromDB(空);
///一些填充值和填充新条件的代码
CriteriaCollection.Add(newCriteria);
}).ContinueWith(结果=>
{
IsBusy=false;
});
}
}
}
我在CriteriaCollection.Add(newCriteria)行得到一个异常;声明此类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection。
有人能帮我吗
谢谢大家! GUI相关代码只能从GUI线程执行,或使用另一个线程的调度程序执行:
Application.Current.Dispatcher.Invoke(new Action(() =>
{
// your GUI related code here
}));
您用于创建任务以进行后台工作的代码不太正确,我相信您需要类似以下内容:
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;
});
}
}
}
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());
IsBusy=true;
Task.Factory.StartNew(()=>
{
Criteria newCriteria=新标准();
返回ExecuteGetDataFromDB(newCriteria);
},CancellationToken.None,TaskCreationOptions.LongRunning,TaskScheduler.Default)
.ContinueWith(t=>
{
标准集合。添加(t.Result);
IsBusy=false;
},TaskScheduler.FromCurrentSynchronizationContext());
这样做的目的是在后台线程上创建任务,当任务完成时,在UI线程上“继续”,希望您不会再遇到异常
注意,您必须将类SomeResult
定义为ExecuteGetDataFromDB
方法的返回类型