假设我有:
ethernet_adapter.PacketArrived += (s, e) =>
{
//long processing...
};
处理可能需要很长时间,而当它处于中间时,另一个数据包已经到达。接下来会发生什么:处理完成后再触发另一个事件,或者新事件可能会在新线程上立即触发?
答案 0 :(得分:2)
这可能是同步操作。它将在另一个线程上发生的唯一方法是,如果引发事件的对象在另一个线程上执行,或者如果您在处理程序中执行此操作。有很多方法可以做到这一点,但如果使用.NET 4,通常首选使用System.Threading.Tasks.Task
。
仔细考虑您希望应用程序的行为方式。简单地处理新线程上的每个数据包可能导致数据包无序处理。您可能希望将它们排队,然后让后台线程处理它们。或者你可能根本不需要做任何事情。
答案 1 :(得分:2)
你不应该假设。它可以是任何取决于按类型(ethernet_adapter
对象)引发事件的方式。
如果是同步操作,则在当前操作正在进行之前不会引发新事件。
如果是异步操作,将立即引发新事件。
答案 2 :(得分:0)
你可以在ThreadPool中排队整个任务,如下所示。
ethernet_adapter.PacketArrived += (s, e) =>
{
ThreadPool.QueueUserWorkItem("long processing item");
};
或者您可以为每个线程创建任务(.net 4.0)。
答案 3 :(得分:0)
据说你的ethernet_adapter
课程中有一种方法:
protected virtual void OnPacketArrived(PacketArrivedEventArgs e)
{
EventHandler<PacketArrivedEventArgs> handler = this.PacketArrived;
if (handler != null)
{
handler(this, e);
}
}
如此长的处理同步订阅者(如您的示例中所示)将阻止所有订阅者的内部枚举。但!如果OnPacketArrived
每次在不同的线程上调用它,它可能不会阻止对ethernet_adapter
的后续调用 - 因此您将获得两个并发的长处理,依此类推。
作为一个例子,看一下Socket
实现:它的异步方法导致在IOCP线程上调用完成回调 - 每次IO ThreadPool
中都有不同的时候。