2012-12-26 54 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每次都不同。