View, Model 및 ViewModel은 기존 MVVM 패턴으로 구현 된 WPF 응용 프로그램을 가지고 있지만 솔루션에는 세 가지 프로젝트가 있습니다.다른 프로젝트에있을 때 SynchronizationContext를 ViewModel에 전달하십시오.
내 ViewModel에
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;
}
}
}
bq.QueueTask (this.ExecuteCommand)에 AsyncObservebleCollection의 구현을 잘 알고있다 -> BackgroundWorker에는 백그라운드 스레드에서 명령을 실행하고 그것은 업데이트 메시지 속성에 분부되는 내 견해.
AsyncObservebleCollection에 UI의 SynchronizationContext가 없기 때문에 스레드 위반 예외가 발생합니다. ViewModel이 뷰에 대해 알지 않아야한다는 것을 알고 있기 때문에 어떻게 문제를 해결할 수 있습니까? UI의 SynchronizationContext를 사용하여 RelayCommand를 비동기 적으로 실행하고 UI를 업데이트하려면 어떻게합니까?
다음public class YourViewModel {
public YourViewModel(Action<Action> beginInvoke)
{
this.BeginInvoke = beginInvoke;
}
protected Action<Action> BeginInvoke { get; private set; }
private void SomeMethod()
{
this.BeginInvoke(() => DoSomething());
} }
이 클래스 (인스턴스화하는 :
는 디스패처에 액세스 할 수없는 경우, 당신은 당신의 클래스에 BeginInvoke 방법의 대리자를 전달할 수 있습니다 당신에게
viewmodel에보기의 디스패처를 전달하는 것이 좋습니까? – inside
실제로 발송자가 필요하지 않을 수 있습니다. 뷰 모델의 속성을 뷰의 GUI 요소에 바인딩하면 WPF 바인딩 메커니즘이 디스패처를 사용하여 GUI 스레드에 대한 GUI 업데이트를 자동으로 마샬링합니다. 하지만 상황이 많다면이 작업을 수행해야 할 수도 있습니다. UI에 바인딩 된 ObservableCollection을 상상해보십시오. 작업자 스레드에서 _collection.Add()를 호출하려고합니다. –