假設我有:事件和線程
ethernet_adapter.PacketArrived += (s, e) =>
{
//long processing...
};
處理可能需要很長的時間,而這是在中間的另一數據包到達。接下來會發生什麼:處理完成,然後另一個事件被觸發,或者新的事件立即被觸發,但在一個新的線程上?
假設我有:事件和線程
ethernet_adapter.PacketArrived += (s, e) =>
{
//long processing...
};
處理可能需要很長的時間,而這是在中間的另一數據包到達。接下來會發生什麼:處理完成,然後另一個事件被觸發,或者新的事件立即被觸發,但在一個新的線程上?
你不應該假設。它可以是任何事情,取決於事件如何按類型(ethernet_adapter
對象)引發。
如果是同步操作,則在當前操作正在進行之前不會引發新事件。
如果是異步操作,則會立即引發新事件。
很可能是同步操作。它在另一個線程上發生的唯一方式是如果引發該事件的對象在另一個線程上執行,或者在處理程序中執行。有很多方法可以做到這一點,但如果使用.NET 4,通常會優先使用System.Threading.Tasks.Task
。
請仔細考慮您希望應用程序的行爲。在新線程上簡單處理每個數據包可能會導致數據包無序處理。您可能希望將它們排隊並在後面有一個後臺線程處理它們。或者你可能不需要做任何事情。
據說有一個在您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
每次都不同。
什麼類型的對象是'ethernet_adapter'? –
@JimMischel它是第三方庫類型'ICaptureDevice'。我想我得到了答案。 – ren