2009-03-05 27 views
2

我目前有一個線程可以偵聽來自網絡的數據,然後在其上運行規則。然後我想將數據傳遞給GUI。我擔心在GUI中發生死鎖。我無法弄清楚把互斥體放在GUI一邊。我也使用c#和dotnet 3.5。Winforms應該我多線程或使用事件計時器?

我想到的是 1)使用計時器來創建事件並轉儲線程。擔心表現。 2)使用中間事件將數據複製到GUI。 3)挖掘並找出使用GUI的線程安全方式。

您認爲最好的方法是什麼?

編輯:這是我正在使用的解決方案。我傳入更改後的元素,然後用互斥鎖保護大對象。我使用幫助函數切換線程使用InvokeRequired然後BeginInvoke與委託。從閱讀答案拉動,然後跟隨鏈接,直到達到Threading in Windows FormsJon Skeet

delegate void UInt32ParameterDelegate(UInt32 n); 

    public void UpdateLocation(UInt32 n) 
    { 
    if (InvokeRequired) 
    { 
     // We're not in the UI thread, so we need to call BeginInvoke 
     BeginInvoke(new UInt32ParameterDelegate(UpdateLocation), new object[] { n }); 
     return; 
    } 
    // Must be on the UI thread if we've got this far 

    this.engine.location.UpdateBusy.WaitOne(); 
    // do the work in here 

    this.engine.location.UpdateBusy.ReleaseMutex(); 

    } 
+0

您使用.net 2.0嗎? – JoshBerke 2009-03-05 16:15:34

回答

3

Windows窗體中的同步非常簡單。您可以在後臺線程中調用Control.Invoke()。線程將停止運行,直到委託在UI線程上完成運行。根本不需要同步。

如果拖延線程是一個問題,請使用Control.BeginInvoke()。如果線程在繼續運行時可能會改變它,則必須使用鎖來保護傳遞給委託的對象。在生產者 - 消費者場景中情況很少,線程可以簡單地創建新對象。

確保您不經常調用()。更頻繁地執行此操作的次數超過每秒約1000次,並且UI線程將停止泵送Windows消息,並因處理調用請求而陷入停滯狀態。由於它是你想討好的人類眼睛,每秒調用超過25次以上就是浪費精力。池中間結果集合對象。

+0

+1,可以很好地解答Windows窗體中的同步問題。 – 2012-10-19 00:18:41

0

只是拋出一個委託人提出事件通知表單刷新自己不容易嗎?

2

從不在GUI線程上從網絡讀取。在網絡中斷期間運行應用程序只是時間問題,因此GUI會掛起。這會讓你的用戶感到非常失望。

在你的情況下,我認爲最好的辦法是讓後臺線程完成讀取操作。然後獲取結果數據並通過SynchronizationContext Post或Send方法將其移回GUI線程。

3

我希望我能正確理解你的問題。

在後臺線程讀取數據並執行任何想要的操作後,應該使用Invoke在GUI線程上調用方法。該方法會更新GUI中應該更新的任何內容。

1

你可以使用一個backgroundworker將處理在後臺線程的datareading並且當它這樣做,你可以結束BackgroundWorker的觸發它的RunWorkerCompletedEventHandler。在RunWorkerCompletedEventHandler中,您可以使用結果更新您的GUI線程。

相關問題