WPF调度员、后台工作人员和一大堆痛苦
好吧,这可能真的很简单,但我尝试的每件事似乎都碰壁了 我有一个具有两个属性的视图模型,它们绑定到我的WPF表单:WPF调度员、后台工作人员和一大堆痛苦,wpf,mvvm,multithreading,backgroundworker,dispatcher,Wpf,Mvvm,Multithreading,Backgroundworker,Dispatcher,好吧,这可能真的很简单,但我尝试的每件事似乎都碰壁了 我有一个具有两个属性的视图模型,它们绑定到我的WPF表单: bool IsWorking {get;set;} ObservableCollection<OtherViewModel> PendingItems {get;set;} 现在worker_DoWork调用一个方法,该方法将获取挂起的项并将它们添加到PendingItems集合中,所有内容都在后台运行UI仍有响应,但我在尝试添加到集合时遇到了正常的跨线程错误。我在
bool IsWorking {get;set;}
ObservableCollection<OtherViewModel> PendingItems {get;set;}
现在worker_DoWork调用一个方法,该方法将获取挂起的项并将它们添加到PendingItems集合中,所有内容都在后台运行UI仍有响应,但我在尝试添加到集合时遇到了正常的跨线程错误。我在dispatcher调用中包装了更改集合的代码:
// Update to show the status dialog.
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Render,
new Action(delegate()
{
this.PendingItems.Add(\\Blah);
})
);
但它仍然抛出相同的跨线程错误
我不太擅长线程,所以我不知道我可能做错了什么,有人能帮我一下吗?看看其他人是如何创建线程安全的可观察集合的信息(所以你不必这么做)。因为更新集合的代码是从后台线程调用的,Dispatcher.CurrentDispatcher是错误的调度器。您需要保留对UI调度程序的引用,并在计划更新时使用该调度程序。根据 因为您在新线程(由worker创建)中调用Dispatcher.CurrentDispatcher,所以它会创建新的Dispatcher对象。 因此,您应该以某种方式从调用线程(ui线程)获取dispatcher。 另一个选项是将ui调度程序作为参数传递给worker.RunWorkerAsync(对象参数)
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync(Dispatcher.CurrentDispatcher);
...
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
Dispatcher dispatcher = e.Argument as Dispatcher; // this is right ui dispatcher
// Update to show the status dialog.
dispatcher.Invoke(DispatcherPriority.Render,
new Action(delegate()
{
this.PendingItems.Add(\\Blah);
})
);
}
第二个环节是死的。有什么想法吗?第一个链接已经死了。@Jesslyn这是因为我当时不知道它是如何工作的。一个只指向链接的答案是一个相当糟糕的答案,我应该自己投票否决它。
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync(Dispatcher.CurrentDispatcher);
...
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
Dispatcher dispatcher = e.Argument as Dispatcher; // this is right ui dispatcher
// Update to show the status dialog.
dispatcher.Invoke(DispatcherPriority.Render,
new Action(delegate()
{
this.PendingItems.Add(\\Blah);
})
);
}