我正在尝试运行类似后台线程的东西,并通过引发事件来通知ViewModel此后台线程的状态。 ViewModel反过来引发OnPropertyChanged事件。不幸的是,相应的视图不会更新。
我通知ViewModel的后台线程部分可以在这里看到:
private void RunThread() {
while(true) {
suspendEvent.WaitOne(Timeout.Infinite);
if (shutDownEvent.WaitOne(0)) {
break;
}
if (pauseEvent.WaitOne(0)) {
pauseEvent.Reset();
}
Notify("Cleaning started!");
pauseEvent.WaitOne(TimeSpan.FromSeconds(5));
Clean();
Notify("Cleaning finished!");
pauseEvent.WaitOne(TimeSpan.FromSeconds(5));
}
}
private void Notify( String status ) {
NotifyOfCleanerStatusHandler handler = NotifyOfcleanerStatus;
if (handler != null) {
handler(status);
}
}
我收到该事件的ViewModel部分可以在这里看到:
public void SetCleanerStatus( String status ) {
CleanerStatus = status;
}
最后,我将我的视图绑定到的属性可以在这里看到:
public String CleanerStatus {
get {
return cleanerStatus;
}
set {
if (value != null) {
cleanerStatus = value;
OnPropertyChanged("CleanerStatus");
}
}
}
有趣的是:视图将显示上述状态之一,“清理开始!”或“清洁完毕!”。人们会认为它们应该以5秒的间隔交替。不是这种情况。
如果我删除第一个waithandle调用(pauseEvent.WaitOne(TimeSpan.FromSeconds(5));)视图中的消息是“Cleaning finished”并保持这种状态。如果我保留该行,则消息为“正在清理!”并保持这种方式。调试显示已到达OnPropertyChanged(..)行。
我做错了什么?
答案 0 :(得分:0)
简化您的RunThread方法:
private ManualResetEvent suspendEvent = new ManualResetEvent(false);
private bool shutdown;
private void RunThread()
{
while (!shutdown)
{
suspendEvent.WaitOne();
if (shutdown)
{
break;
}
Notify("Cleaning started!");
Thread.Sleep(TimeSpan.FromSeconds(5));
Notify("Cleaning finished!");
Thread.Sleep(TimeSpan.FromSeconds(5));
}
}
更新UI时,可能还需要在UI线程中调用PropertyChanged
处理程序:
public string CleanerStatus
{
get { return cleanerStatus; }
set
{
cleanerStatus = value;
App.Current.Dispatcher.BeginInvoke(
new Action(() => OnPropertyChanged("CleanerStatus")));
}
}