假设我有:事件和线程
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