2010-06-15 123 views
2

我想重用一個UserControl,並借用一些邏輯來跟蹤進度。我會盡量簡化一些事情。 MyWindow.xaml包含一個MyUserControl。 MyUserControl有其自己的進度指示器(正在格式化...,複製文件...等),我想在MyWindow窗體中的某處反映這一進展。但是,用戶控件有一些我不太明白的邏輯。我已閱讀並閱讀,但我仍然不理解Dispatcher。以下是用戶控件中更新進度的邏輯的摘要。Dispatcher.Invoke爲什麼不觸發UI更新?

this.Dispatcher.Invoke(DispatcherPriority.Input, (Action)(() => 
{ 
    DAProgressIndicator = InfiniteProgress.AddNewInstanceToControl(StatusGrid, new SolidColorBrush(new Color() { A = 170, R = 128, G = 128, B = 128 }), string.Empty); 
       DAProgressIndicator.Message = MediaCardAdminRes.ActivatingCard; 
       ActivateInProgress = true; 
})); 

我以爲我會很聰明,並添加事件的MyUserControl將在ActivateInProgress屬性集邏輯調用。

public bool ActivateInProgress 
    { 
     get 
     { 
     return _activateInProgress; 
     } 
     set 
     { 
     _activateInProgress = value; 
     if (ActivateInProgressHandler != null) 
     { 
      ActivateInProgressHandler(value); 
     } 
     } 
    } 

我設置mywindow的構造函數下面的方法設置一個用於窗口自己的進度指示器視圖模型屬性中的ActivateInProgressHandler。

private void SetActivation(bool activateInProgress) 
{ 
    viewModel.ActivationInProgress = activateInProgress; 
} 

但是,窗口的進度指示不會改變。所以,我確信Dispatcher.Invoke正在做一些我不明白的事情。如果我在SetActivation方法中放置一個消息框,則會更新線程塊和窗口的進度指示器。我瞭解基本的線程,但這個整個Dispatcher對我來說是新事物。我錯過了什麼?

更新:它似乎現在工作。事實證明,進展正在得到如此之快的更新,以至於它從未在屏幕上顯示出來。但是,我仍然想明白爲什麼Dispatcher.Invoke完成了(這是我沒有寫入的現有代碼)。爲什麼不按照* .xaml.cs代碼的其餘部分完成操作內容?

+0

如何更新窗口中的進度條?然而,它必須在一個單獨的線程中完成,然後使用調度程序。 – Amsakanna 2010-06-15 06:03:27

回答

1

你最後一段提到了兩次線程,這就提出了有一個或多個後臺線程的可能性。但是由於您沒有提到應用程序中存在哪些線程,它們是如何創建的,它們是如何交互的等等,我現在假設只有一個線程。

如果UI線程是唯一的線程,問題很明顯:您的UI線程忙於運行正在進行的任務,並且不需要時間來呈現更新的UI。如果是這樣的問題,這可能會解決這個問題:

viewModel.ActivationInProgress = activateInProgress; 
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, 
         new Action(() => {})); 

的BeginInvoke的強制輸入以上所有優先級調度操作完成當前線程繼續之前。

0

分派器在隊列中工作。所以可能是UI線程阻塞。您可以通過Dispatcher在隊列中添加更多工作,但由於UI線程阻塞,永遠不會執行。

也許試試這個:

DispatcherFrame _frame = new DispatcherFrame(); 
Dispatcher.PushFrame(_frame); 

這將使您的工作盈方的工作已經在隊列中。所以UI線程將完成這項工作,然後再次阻止。

相關問題