2012-12-26 52 views
5

假設我有:事件和線程

ethernet_adapter.PacketArrived += (s, e) => 
{ 
    //long processing... 
}; 

處理可能需要很長的時間,而這是在中間的另一數據包到達。接下來會發生什麼:處理完成,然後另一個事件被觸發,或者新的事件立即被觸發,但在一個新的線程上?

+0

什麼類型的對象是'ethernet_adapter'? –

+0

@JimMischel它是第三方庫類型'ICaptureDevice'。我想我得到了答案。 – ren

回答

2

你不應該假設。它可以是任何事情,取決於事件如何按類型(ethernet_adapter對象)引發。

如果是同步操作,則在當前操作正在進行之前不會引發新事件。

如果是異步操作,則會立即引發新事件。

2

很可能是同步操作。它在另一個線程上發生的唯一方式是如果引發該事件的對象在另一個線程上執行,或者在處理程序中執行。有很多方法可以做到這一點,但如果使用.NET 4,通常會優先使用System.Threading.Tasks.Task

請仔細考慮您希望應用程序的行爲。在新線程上簡單處理每個數據包可能會導致數據包無序處理。您可能希望將它們排隊並在後面有一個後臺線程處理它們。或者你可能不需要做任何事情。

0

您可以在ThreadPool中排列整個任務,如下所示。

ethernet_adapter.PacketArrived += (s, e) => 
{ 
ThreadPool.QueueUserWorkItem("long processing item"); 
}; 

或者您可以爲每個線程創建任務(.net 4.0)。

+0

這與OP問題有什麼關係? – Tilak

+0

每個長處理項可以在線程池中排隊,並將相應地服務。我希望我已經理解了這個問題。 – paritosh

+0

我認爲,問題是「什麼是行爲」,而不是「如何進行異步處理」 – Tilak

0

據說有一個在您ethernet_adapter類中的方法:

protected virtual void OnPacketArrived(PacketArrivedEventArgs e) 
{ 
    EventHandler<PacketArrivedEventArgs> handler = this.PacketArrived; 

    if (handler != null) 
    { 
     handler(this, e); 
    } 
} 

所以長的處理同步訂戶(如在你的例子)將阻止內部枚舉在所有訂戶。但!如果ethernet_adapter每次在不同的線程上調用它,它可能不會阻止對OnPacketArrived的後續調用,因此您將得到兩個併發的長處理,依此類推。

舉個例子,看看在Socket實現:它是異步方法造成IOCP線程調用完成回調 - 而有任何的IO ThreadPool每次都不同。