2009-02-24 106 views
4

我有一個類包含一個工作線程,它從循環中的隊列接收數據。C#.NET 3.5:如何調用事件處理程序並等待它完成

該應用程序的另一部分吸收了該類中的事件,該類爲每個隊列項引發。

這些事件是異步觸發的,所以在繁忙的時候,應用的其他部分可以同時處理多個事件。

這應該沒問題,但我們發現了一個可能導致問題的場景。

我們需要一個快速解決方案,同時解決主要問題。框架是否提供了一種簡單的方法,我可以強制工作線程在每個事件得到處理時等待(以便按順序處理)?如果沒有,那麼實現這個最簡單的方法是什麼?

+0

你的代碼的一個小例子會有幫助,對'event'這個詞有多重含義。 – AnthonyWJones 2009-02-24 17:17:41

+0

奇怪的問題,你基本上是說「我異步提高事件,但我想同步做」。事件是默認同步提升的,只是不要做異步引發它們的額外工作。 – 2009-02-24 17:37:35

回答

4

一個簡單的答案是鎖定事件處理程序中的單個對象。所有的隊伍都會等待鎖定。

0

沒有一般的方法。

最後,處理程序需要提供跟蹤機制。

如果您使用的是BeginInvoke,而不是直接引發事件,則可以使用包裝器,在該包裝器中同步調用真實事件處理程序,然後異步提升包裝器。包裝可以維護一個計數器(使用互鎖操作)或設置一個事件以滿足您的需求。

喜歡的東西:

TheDelegate realHandler = theEvent; 
var outer = this; 
ThreadPool.QuereUserWorkItem(x => { 
    // Set start of handler 
    realHandler(outer, eventArgs); 
    // Set handler finished 
}; 
0

所有事件處理程序下沉由隊列讀取工作線程引發的事件被稱爲隊列中讀輔助線程。只要事件處理程序不會產生它們自己的線程,您應該能夠通過調用隊列讀取工作線程上的Thread.Join()來等待事件處理程序完成。

1

我的猜測是,你想簡單地通過引發一個事件並直接調用方法來觸發動作。

AFAIK事件將是異步的,我不知道有任何「簡單」的方法來改變它。

3

ManualResetEvent class可能會幫助你,除非我不理解你的問題。您可以使用它來阻止下一個事件的觸發,直到最後一個事件完成。

1

原來還有另一個答案。您可以將以下屬性添加到方法中。

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]