2013-11-22 32 views
1

我想運行的東西像後臺線程,並通過提高事件通知此背景線程的狀態的ViewModel。 ViewModel反過來引發OnPropertyChanged事件。不幸的是,相應的視圖不會更新。查看不更新時,從另一個線程事件更改屬性

後臺線程的一部分,我通知視圖模型可以在這裏看到:

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); 
     } 
    } 

視圖模型的,我收到事件的部分可以在這裏看到:

public void SetCleanerStatus(String status) { 
     CleanerStatus = status; 
    } 

而且最後,我看到的屬性我看到這裏:

public String CleanerStatus { 
     get { 
      return cleanerStatus; 
     } 
     set { 
      if (value != null) { 
       cleanerStatus = value; 
       OnPropertyChanged("CleanerStatus"); 
      } 
     } 
    } 

有趣的薄g是:視圖將顯示以上狀態之一,即「開始清理!」或「清潔完成!」。人們會認爲它們應該以5秒爲間隔交替。不是這種情況。

如果我刪除第一個waithandle調用(pauseEvent.WaitOne(TimeSpan.FromSeconds(5));)視圖中的消息是「清理完成」並保持這種狀態。如果我保持行,消息是「清潔開始!」並保持這種方式。調試顯示已到達行OnPropertyChanged(..)。

我在做什麼錯?

+0

很奇怪,你在做什麼,爲什麼你想從另一個線程更新屬性ViewModel應該在主線程中工作?! –

+0

處理程序是否在任何時候都爲空? –

+0

我認爲你的lus會立刻崩潰因爲shutdownevent.waitone(0)沒有等待而返回。檢查msdn:「如果millisecondsTimeout爲零,則該方法不會阻塞,它會測試等待句柄的狀態並立即返回。」 - http://msdn.microsoft.com/en-us/library/vstudio/cc189907(v=vs.110).aspx @備註部分 –

回答

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"))); 
    } 
} 
+0

需要其餘的控制柄來控制Cleaner的行爲,但是當然我需要以某種方式重構。不幸的是,你的解決方案不起作用,行爲是一樣的。我發現OnPropertyChanged是從Cleaner線程調用的,所以這可能是問題所在。 – hschne

+0

它適用於我。我已經解決了從後臺線程調用OnPropertyChanged的事實。 – Clemens

+0

好的,非常感謝!原因是一個非常愚蠢的錯誤,我甚至不會提到它是什麼,因爲它是非常愚蠢的。您的解決方案效果很好,再次感謝。 – hschne

相關問題