EnL*_*cha 5 .net c# wpf multithreading
我有一段时间搞清楚如何处理来自ViewModel之外的类的Thread.
Thread来自一个Track类.这是以下ResponseEventHandler代码Track:
public delegate void ResponseEventHandler(AbstractResponse response);
public event ResponseEventHandler OnResponseEvent;
Run Code Online (Sandbox Code Playgroud)
当从我的Track对象中处理"命令"方法时,以下代码运行OnResponseEvent,它将线程中的消息发送回我的ViewModel:
if (OnResponseEvent != null)
{
OnResponseEvent(GetResponseFromCurrentBuffer());
}
Run Code Online (Sandbox Code Playgroud)
GetResponseFromCurrentBuffer()只返回一个消息类型,它是一个预定义的类型Track.
我的MainWindowViewModel构造函数创建了一个事件处理程序OnResponseEvent从Track:
public MainWindowViewModel()
{
Track _Track = new Track();
_Track.OnResponseEvent +=
new Track.ResponseEventHandler(UpdateTrackResponseWindow);
}
Run Code Online (Sandbox Code Playgroud)
所以,我的想法是每次有来自OnResponseEventThread的新消息时,我都会运行该UpdateTrackResponseWindow()方法.此方法将新的消息字符串附加到ObservableCollection<string>名为的列表属性TrackResponseMessage:
private void UpdateTrackResponseWindow(AbstractResponse message)
{
TrackResponseMessage.Add(FormatMessageResponseToString(message));
}
Run Code Online (Sandbox Code Playgroud)
该FormatMessageResponseToString()方法仅将消息与其中的所有预定义消息类型进行比较Track,并进行一些漂亮的字符串格式化.
主要问题是: 运行时UI消失TrackResponseMessage.Add().可执行文件仍在后台运行,结束任务的唯一方法是关闭Visual Studio 2010.
TrackResponseMessage 是我的ViewModel中的公共属性:
public ObservableCollection<String> TrackResponseMessage
{
get { return _trackResponseMessage; }
set
{
_trackResponseMessage = value;
RaisePropertyChanged("TrackResponseMessage");
}
}
Run Code Online (Sandbox Code Playgroud)
是否需要我将Thread来自Track对象的内容编组到我的ViewModel中?任何示例代码将非常感谢!
Ree*_*sey 10
我是否需要编组从Track.cs对象到我的viewmodel的线程?任何示例代码将非常感谢!
是.不幸的是,虽然INotifyPropertyChanged将处理来自其他线程的事件,INotifyCollectionChanged但不会(即:) ObservableCollection<T>.因此,您需要编组回VM.
如果从View(View-First MVVM)创建VM或者已知在UI线程上创建VM,则使用.NET 4任务有一个很好的选择:
TaskScheduler uiScheduler;
public MainWindowViewModel()
{
uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Track _Track = new Track();
_Track.OnResponseEvent += new Track.ResponseEventHandler(UpdateTrackResponseWindow);
}
Run Code Online (Sandbox Code Playgroud)
然后,您的事件处理程序可以执行以下操作:
private void UpdateTrackResponseWindow(AbstractResponse message)
{
Task.Factory.StartNew(
() => TrackResponseMessage.Add(FormatMessageResponseToString(message)),
CancellationToken.None, TaskCreationOptions.None,
uiScheduler);
}
Run Code Online (Sandbox Code Playgroud)
这样做的好处是不会将WPF或Silverlight特定的资源和类型提取到ViewModel类中(即:)Dispatcher,同时仍然提供所有好处.它在具有线程亲和性的其他例程中也可以不变地工作(即:WCF服务工作).
| 归档时间: |
|
| 查看次数: |
4678 次 |
| 最近记录: |