2012-04-07 56 views
0

我最近爲服務器獲取了控制檯包裝器的一些源代碼。該方案的淵源在WPF和部分代碼是:將WPF調度程序轉換爲Winforms BGworker?

private void ServerProc_ErrorDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     Dispatcher.Invoke(new Action(() => 
     { 
      ConsoleTextBlock.Text += e.Data + "\r\n"; 
      ConsoleScroll.ScrollToEnd(); 
     })); 
    } 
    private void ServerProc_OutputDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     Dispatcher.Invoke(new Action(() => 
     { 
      ConsoleTextBlock.Text += e.Data + "\r\n"; 
      ConsoleScroll.ScrollToEnd(); 
      ParseServerInput(e.Data); 
     })); 
    } 

它也有過這樣的註釋在兩個空隙:

//你必須通過調度員要做到這一點,因爲這種方法是 由不同的線程調用

但是在WinForms中沒有這樣的事情 - 是否有辦法將其更改爲後臺工作人員或某事(我幾乎沒有做任何多線程)?

如果有人可以幫助,那太棒了!

謝謝。

回答

1

這兩種方法都是事件處理程序。機會來自某種偵聽代碼,我希望它們是從非UI線程調用的(例如,通常是正在執行偵聽的線程池線程)。您可以通過放置一個斷點並在調試器中查看線程窗口來檢查該問題。
因此,您需要應用winforms從非UI線程更新UI的方式。
如果你搜索,你應該找到很多關於如何做到這一點。 E.g
Updating UI from a different thread
How to update GUI from another thread in C#?

+0

謝謝,但即時通訊不太確定我可以如何將它應用到我的代碼 - 我更好地使用VB.NET,仍然習慣C# – 2012-04-07 13:08:59

0

一些背景:這是所有非UI線程的線程上運行的過程中是不允許訪問任何UI直接控制。您的WPF ServerProc運行在與您的UI不同的線程中,這需要Dispatcher幫助您從ServerProc線程返回到UI線程中的UI控件。

如果您的ServerProc - 在WPF或WinForms中 - 在UI線程中運行,則不需要用Dispatcher.Invoke調用將其包圍。

對於你,你可以把你的ServerProc放在BackgroundWorker (MSDN example)。您的DoWork方法將包含執行該工作的代碼,然後根據ServerProc的工作方式,您可能可以使用ProgressChanged來執行您的示例WPF方法正在執行的操作。 ProgressChanged有一個參數傳入,您可以指出它是否是錯誤或已收到數據,並且在函數內部可以顯示相應的信息。看看MSDN文檔,因爲他們有一個很好的例子。

重要的是要指出ProgressChanged發生在UI線程上,所以你不需要用Invoke將你的調用包圍在你的UI控件中;只是給他們打電話吧。 RunWorkerCompleted也是一樣,這可能是ServerProc完成作業時顯示數據的其他選項。最後,如果你實際上必須從你的線程中訪問一個UI控件,你可以做一些與你的WPF代碼示例非常相似的東西。看看MethodInvoker。而不是分派器,你真的只是從你的主窗體調用它。

+0

問題是ServerProc方法都是事件處理程序 - 並且將由現有代碼在非UI線程上。我記得在這種情況下,BackgroundWorker如何提供幫助?我不認爲他想重寫現有的服務器偵聽/事件觸發代碼 - 只是事件處理程序 - 已經存在於非UI線程中。 – Ricibob 2012-04-07 13:14:06

+0

非常感謝! ; D我使用了方法調用者!不,我終於可以得到這個應用程序。很好的幫助。謝謝。 – 2012-04-07 13:14:30

+0

@AlexOgden如果這爲您提供了一個解決方案,那麼您應該通過點擊左側的勾號將其標記爲已接受的答案。 – Ricibob 2012-04-08 08:26:49

相關問題