2011-05-18 60 views
11

我開發了一個大量使用事件的C#應用​​程序。現在,這個應用程序偶爾會做一些我無法理解的有趣事情,或者追蹤它們爲什麼會發生的具體原因。我認爲造成這些間歇性故障的原因是某種我沒有預料到的併發或競爭狀況。什麼時候在C#中執行事件?

在C#中事件處理的確切程度?如果發生事件,將(a)與該事件相關的代碼部分立即執行?或者將事件(b)放在一堆事件上並在.NET認爲適合執行時執行,同時執行其他代碼?

回答

12

如果引發事件,將代碼的部分連接到該事件立即執行?

嗯,是的,沒有。事件是多播委託,所以可能有零個,一個或多個「部分代碼」附加到一個事件。在場景很多的情況下,顯然其中一個必須先走,其中一個必須走第二個。在事件發生後,立即執行的事件不會立即執行;它會在第一個事件處理程序正常完成時立即執行。

將事件放在一堆事件上,並在.NET認爲適合執行時執行,同時執行其他代碼?

假設您的應用程序寫得很糟糕並掛起了用戶界面。當用戶界面掛起時,用戶點擊按鈕1和按鈕2.由於應用程序掛起,沒有任何可見的情況發生。點擊按鈕1和按鈕2的事件不會觸發。但是Windows已經創建了一個消息隊列,並在隊列中放入了按鈕1和按鈕2在應用程序懸空時需要處理的待處理點擊事件。當消息循環被抽取時,按鈕1點擊事件觸發。當它完成它的事情時,消息循環再次被泵送,按鈕2點擊事件觸發。因此,從這個意義上說,事件排隊並在稍後執行,但它不是「當.NET認爲它適合時」。正在處理消息隊列的線程開始再次處理消息隊列。在這裏控制你的代碼沒有神祕的Windows策略。

+0

「當它完成它的事情後,消息循環再次被泵送,按鈕1單擊事件觸發。」你的意思是按鈕2點擊事件?「 – Brian 2011-05-18 13:40:51

5

與其他代表一樣,C#事件在觸發時立即執行

8

它完全取決於事件引發(和訂閱)代碼。

如果你提出這樣的事件:

EventHandler handler = MyEvent; 

if (handler != null) 
{ 
    handler(this, EventArgs.Empty); 
} 

或類似的東西,那麼所有的事件處理程序將立即執行。這就是典型的實現......你必須努力將每個事件委託放入WinForms消息隊列或類似的東西。

如果您可以向我們提供有關您正在討論的活動以及實施方式的更多信息,我們可能會爲您提供更多幫助。

有關活動和代表(以及它們之間的差異)的更多信息,您可能需要閱讀my article on the topic

2

除非另有明確規定,否則同步調用事件。

通常觸發一個事件的代碼看起來像這樣:

public event EventHandler MyEvent; 

protected virtual void OnMyEvent() 
{ 
    EventHandler handler = MyEvent; // keep a copy to avoid race conditions 
    if (handler != null) 
     handler(this, EventArgs.Empty); 
} 

正如你可以從這個代碼中看到,事件處理程序會立即同步從OnMyEvent方法調用。

1

我相信你的問題已經在這裏找到答案:

Are Event Handlers processed Asynchronously?

總之,這取決於具體的實現,但是默認的事件處理進行同步處理。但是,有一些方法可以使其異步。

0

正如前面的awnser所述,它完全取決於引發事件或處理事件的代碼。

上面的例子缺少的是正確的代碼如何提升/處理事件。我知道他們只是簡單的例子,但是,好的做法非常重要。

如果你想很好的例子/如何事件可以在C#中正確處理的材料,你可以看看這篇文章:http://www.codeproject.com/KB/cs/event_fundamentals.aspx

相關問題