C# 将SynchronizationContext传递给ViewModel,当它';他在另一个项目中
我用经典的MVVM模式实现了WPF应用程序,但是在我的解决方案中,View、Model和ViewModel是三个不同的项目 我在我的ViewModel中有一个众所周知的实现C# 将SynchronizationContext传递给ViewModel,当它';他在另一个项目中,c#,wpf,asynchronous,relaycommand,synchronizationcontext,C#,Wpf,Asynchronous,Relaycommand,Synchronizationcontext,我用经典的MVVM模式实现了WPF应用程序,但是在我的解决方案中,View、Model和ViewModel是三个不同的项目 我在我的ViewModel中有一个众所周知的实现 public class MyVM : ViewModelBase { private RelayCommand _runCommand; private AsyncObservebleCollection _messages; public AsyncObservebleCollection<
public class MyVM : ViewModelBase
{
private RelayCommand _runCommand;
private AsyncObservebleCollection _messages;
public AsyncObservebleCollection<Message> Messages
{
get
{
return _messages;
}
set
{
_messages = value; NotifyPropertyChanged();
}
}
public ICommand RunCommand
{
get
{
if (_runCommand == null)
{
_runCommand = new RelayCommand(executeParam =>
bq.QueueTask(this.ExecuteCommand),
canExecuteParam => true);
}
return _runCommand;
}
}
}
公共类MyVM:ViewModelBase
{
专用中继命令_runCommand;
专用AsyncObservebleCollection\u消息;
公共AsyncObservebleCollection消息
{
收到
{
返回消息;
}
设置
{
_messages=value;NotifyPropertyChanged();
}
}
公共ICommand运行命令
{
收到
{
如果(_runCommand==null)
{
_runCommand=newrelaycommand(executeParam=>
QueueTask(this.ExecuteCommand),
canExecuteParam=>true);
}
返回运行命令;
}
}
}
QueueTask(this.ExecuteCommand)->backgroundWorker正在后台线程上执行命令,并且
更新“我的视图”中的“消息”属性
现在,我得到了线程冲突异常,因为AsyncObservebleCollection没有UI的SynchronizationContext,而且因为我知道ViewModel不应该知道视图,我该如何解决我的问题?如何使用UI的SynchronizationContext异步运行RelayCommand并更新UI
谢谢如果您无权访问Dispatcher,只需将BeginInvoke方法的委托传递给您的类:
public class YourViewModel {
public YourViewModel(Action<Action> beginInvoke)
{
this.BeginInvoke = beginInvoke;
}
protected Action<Action> BeginInvoke { get; private set; }
private void SomeMethod()
{
this.BeginInvoke(() => DoSomething());
} }
实际上,您可能不需要调度器。如果将viewmodel上的属性绑定到视图中的GUI元素,则WPF绑定机制会使用dispatcher自动将GUI更新封送到GUI线程。但是在很多情况下,您可能需要这样做,想象一个绑定到UI的ObservableCollection,您试图从工作线程调用_collection.Add()
var dispatcherDelegate = action => Dispatcher.BeginInvoke(action);
var viewModel = new YourViewModel(dispatcherDelegate);