2012-03-13 68 views
0

我有一個主要的GUI應用程序,它完成了它在引用程序集中的實際工作。現在,我不會在後臺工作人員中完成這項工作,因此它在處理主要用戶界面時基本上鎖定了它。在我引用的組合中,我添加了很多事件來向主UI表單報告不同的進度。在主UI形式上,我使用這些事件的值更新不同的文本框。我的問題是,首先,處理這些事件的過程似乎要慢得多。那麼我應該在輔助線程(從引用的程序集)上觸發事件嗎?我最初的電話是否應該通過後臺工作人員進行引用(靜態)?我想在一個單獨的線程上報告不同類型的進度,但不確定採用哪種方法來獲得最佳性能。我是否需要實現後臺工作人員

感謝

回答

1

從你的描述,它聽起來就像你會從多線程中獲益,因爲這將有助於保持UI響應。

而最簡單的方法是使用BackgroundWorker。從one of the many samples開始,然後咬下子彈,如果有任何問題,請回到這裏。

在迴應評論:

從一個BackgroundWorker工作線程的主線程進行溝通的最佳方式是調用BackgroundWorker.ReportProgress方法,它帶有一個可選的對象參數userState,你可以用它來打包你想要溝通的數據。

這會導致在主線程上引發BackgroundWorker.ProgressChanged事件 - 並且可以在不需要顯式Invoke的情況下處理數據。

如果您已經實施了事件,您必須重新調用ReportProgress而不是提高事件,或者實施某種適配器來處理事件並將它們路由到ReportProgress方法調用。

+0

感謝@Joe,我對BackgroundWorker或多線程沒有問題,但我想我更好奇,如果引用的程序集職責是通過BackgroundWorker啓動的,並且它們的靜態事件是從BackgroundWorker的線程觸發的,調用表單在主UI線程上接收它們,還是在Background線程上接收到它們? – ganders 2012-03-13 17:48:58

0

你可以在不同的線程啓動的過程(在其它組件的方法),以及處理由它在主窗體上引發的事件。

由於UI不能被另一個線程更新,所以應該將這些事件的代碼包裝在this.Invoke()中。

例:

private void TheEventRaisedOnAnotherThread(object sender, EventArgs e) 
{ 
    _counter++; 
    this.Invoke(new MethodInvoker(delegate() { TextBox1.Text = _counter.ToString(); })); 
} 
+0

謝謝@matap,所以我只是設置一個輔助線程來調用我的「ReferencedAssembly.Go()」方法。然後,由ReferencedAssembly類引發的事件將通過主UI線程接收,對吧? 輔助線程aka BackgroundWorker – ganders 2012-03-13 17:50:26

+0

如果在新線程上調用ReferencedAssembly.Go,它的事件將在新線程上執行,而不是在主UI線程上執行。因此,這就是爲什麼你應該使用this.Invoke()更新你的UI。 – 2012-03-13 20:14:50