2012-04-26 96 views
0

今天我將嘗試瞭解WPF中的多線程進程。 所以我做了一個只有一個窗口的WPF應用程序。在窗口中,你會發現一個按鈕和一個文本框 - 沒有別的:WPF多線程屬性更新不起作用異步

<Window x:Class="Multithreading.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <Button Content="Button" Height="23" Name="button1" Width="75" Click="button1_Click" /> 
    <TextBox Height="23" Name="txtCounter" VerticalAlignment="Top" Width="120" /> 
</Grid> 

好 - 讓我們來看看我的單擊事件:

private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     ThreadStart ts = delegate 
     { 
      Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(Threddy)); 
     }; 
     new Thread(ts).Start(); 
    } 

正如你可以看到有一個代表 - 方法「Threddy」:

public void Threddy() 
    { 
     for (int i = 0; i < 10000; i++) 
     { 
      txtCounter.Text = "" + i; 
     } 
    } 

我現在希望是清楚我想要做的事: 我如果用戶單擊該按鈕,則應啓動一個新線程,這會更改我的文本框的文本。但不幸的是,文本只改變了一次:最後。

所以 - 我做錯了什麼? 感謝您的幫助!

CodeCannibal

回答

0

認爲你confussing開始你的線程異步與發佈你的線程代碼異步。
你想要啓動另一個線程,並從那個更新UI線程控制。 WPF不會允許你更新從另一個線程在UI線程上創建的控件,所以你將不得不使用調度器將控制更新代碼發佈到UI線程。這是Theddy中的Dispatcher包裝器。

private void button1_Click(object sender, RoutedEventArgs e) { 
    ThreadStart ts = new ThreadStart(Threddy); 
    new Thread(ts).Start(); 
} 

public void Threddy() { 
    for (int i = 0; i < 10000; i++){ 
     Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { 
      txtCounter.Text = "" + i; 
     })); 
    } 
} 

請注意,在循環內可以BeginInvoke或Invoke。
前者(BeginInvoke)意味着Threddy循環將繼續運行並且不會等待UI更新 - 即(UI更新)將發生,但循環不會等待它。 UI和循環計數器都取得了進展,但不一定同步。
後面的(調用)意味着你的循環的每個執行都會等待直到UI控件實際更新。 UI和循環計數器同步。

+0

我知道你的意思,但我確實試過了你的代碼 - 但結果仍然是一樣的。好的 - 如果我選擇INVOKE而不是文本屬性更改,但不是一步一步:)(始終爲+1)。任何想法爲什麼? – CodeCannibal 2012-04-26 13:38:58

+0

如果你開始啓動,那麼循環執行將會很快發生,即它不會等待UI更新並在幾毫秒內完成。所有要發佈到UI的10000次調用都將使Dispatcher超載 - 可能只發布最後一次。嘗試在你的循環中添加一個小睡眠(例如睡眠(300);)。在Invoke情況下,循環應該以UI更新的速度執行,因爲它在繼續下一次迭代之前等待每個UI更新 - 所以我會預期控件應該每次更新1次 - 但我必須承認我沒有運行代碼。 – Ricibob 2012-04-26 13:46:17