像是RS232的資料傳輸,我是透過Thread去執行
原始程式碼如下:
using System; using System.Threading; using System.Windows; namespace WpfApplicationTest { /// <summary> /// MainWindow.xaml 的互動邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private Thread th; private void MainButton_Update_Click(object sender, RoutedEventArgs e) { if (th == null) { th = new Thread(new ThreadStart(Update)); th.Start(); } } private void Update() { while (true) { int random_Number = new Random().Next(); MainLabel_test.Content = random_Number; Thread.Sleep(1000); } } } }
會出現這樣錯誤,是因為『不能跨執行緒去存取資源』
所以,我參考了這篇文章『[C#][WPF][Windows Form] 雙平台通用的跨執行緒存取UI』,寫得非常詳細,不過還是要自己寫看看。
他主要是提出使用『SynchronizationContext』
SynchronizationContext:類別是一種基本類別,用來提供沒有同步處理的無限制執行緒內容。
修改過得程式碼如下:
using System; using System.Threading; using System.Windows; namespace WpfApplicationTest { /// <summary> /// MainWindow.xaml 的互動邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); //取得目前執行緒 sync = SynchronizationContext.Current; } private Thread th; private SynchronizationContext sync; private void MainButton_Update_Click(object sender, RoutedEventArgs e) { if (th == null) { th = new Thread(new ThreadStart(Update)); th.Start(); } } private void Update() { while (true) { int random_Number = new Random().Next(); sync.Send(new SendOrPostCallback(SyncUpdate), random_Number); Thread.Sleep(1000); } } private void SyncUpdate(object state) { MainLabel_test.Content = state; } } }
先看到建構子的程式碼
public MainWindow() { InitializeComponent(); //取得目前執行緒 sync = SynchronizationContext.Current; }
sync是宣告成SynchronizationContext變數,並且設定為當前視窗的主執行緒
使用SynchronizationContext的Send方法讓同步訊息可以同步執行
private void Update() { while (true) { int random_Number = new Random().Next(); sync.Send(new SendOrPostCallback(SyncUpdate), random_Number); Thread.Sleep(1000); } }
並透過SendOrPostCallback委派,將值更新到MainLabel_test
private void SyncUpdate(object state) { MainLabel_test.Content = state; }
執行結果:
我相信看完『MSDN 雜誌:平行計算 - SynchronizationContext 綜述』會更懂得箇中奧義
參考資料:
http://www.dotblogs.com.tw/optimist9266/archive/2011/06/08/27440.aspx
http://msdn.microsoft.com/zh-tw/library/System.Threading.SynchronizationContext(v=vs.80).aspx
http://msdn.microsoft.com/zh-tw/library/system.random(v=vs.110).aspx
http://msdn.microsoft.com/zh-tw/magazine/gg598924.aspx