我花了很长时间弄清楚如何处理来 self 的 ViewModel 之外的类的线程。
线程源自 Track
类(class)。这是 ResponseEventHandler
Track
中的代码:
public delegate void ResponseEventHandler(AbstractResponse response);
public event ResponseEventHandler OnResponseEvent;
当从我的 Track
中处理“命令”方法时对象,以下代码运行 OnResponseEvent
,它将线程中的消息发送回我的 ViewModel:
if (OnResponseEvent != null)
{
OnResponseEvent(GetResponseFromCurrentBuffer());
}
GetResponseFromCurrentBuffer()
仅返回一个消息类型,它是 Track
中的预定义类型.
我的 MainWindowViewModel
构造函数为 OnResponseEvent
创建事件处理程序来自 Track
:
public MainWindowViewModel()
{
Track _Track = new Track();
_Track.OnResponseEvent +=
new Track.ResponseEventHandler(UpdateTrackResponseWindow);
}
所以,我的想法是,每次我收到来自 OnResponseEvent
的新消息时线程,我运行 UpdateTrackResponseWindow()
方法。此方法会将新消息字符串附加到 ObservableCollection<string>
列出名为 TrackResponseMessage
的属性:
private void UpdateTrackResponseWindow(AbstractResponse message)
{
TrackResponseMessage.Add(FormatMessageResponseToString(message));
}
FormatMessageResponseToString()
方法仅将消息与 Track
中的所有预定义消息类型进行比较,并进行一些巧妙的字符串格式化。
主要问题是:当 TrackResponseMessage.Add()
时,UI 消失了。正在运行。可执行文件仍在后台运行,结束任务的唯一方法是关闭 Visual Studio 2010。
TrackResponseMessage
是我的 ViewModel 中的公共(public)属性:
public ObservableCollection<String> TrackResponseMessage
{
get { return _trackResponseMessage; }
set
{
_trackResponseMessage = value;
RaisePropertyChanged("TrackResponseMessage");
}
}
我是否需要编码 Thread
来自 Track
反对我的 ViewModel?任何示例代码将不胜感激!
最佳答案
Is there a need for me to marshall the thread comming from the Track.cs object to my viewmodel? Any example code would be very appreciated!
是的。不幸的是,虽然 INotifyPropertyChanged
将处理来自其他线程的事件,INotifyCollectionChanged
没有(即:ObservableCollection<T>
)。因此,您需要编码回 VM。
如果 VM 是从 View 创建的(View-First MVVM)或已知是在 UI 线程上创建的,那么使用 .NET 4 任务是一个不错的选择:
TaskScheduler uiScheduler;
public MainWindowViewModel()
{
uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Track _Track = new Track();
_Track.OnResponseEvent += new Track.ResponseEventHandler(UpdateTrackResponseWindow);
}
然后,稍后,您的事件处理程序可以执行以下操作:
private void UpdateTrackResponseWindow(AbstractResponse message)
{
Task.Factory.StartNew(
() => TrackResponseMessage.Add(FormatMessageResponseToString(message)),
CancellationToken.None, TaskCreationOptions.None,
uiScheduler);
}
这具有不将 WPF 或 Silverlight 特定资源和类型拉入您的 ViewModel 类(即:Dispatcher
)的好处,同时仍提供所有好处。它也可以在其他具有线程亲和性的例程中保持不变(即:WCF 服务工作)。
关于c# - 如何在 MVVM View 模型中处理 C# WPF 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6538633/