私が持っているとします:
ethernet_adapter.PacketArrived += (s, e) =>
{
//long processing...
};
処理に時間がかかる場合があり、処理の途中で別のパケットが到着しました。次に何が起こるか: 処理が完了してから別のイベントが発生するか、新しいイベントがすぐに新しいスレッドで発生するのでしょうか?
私が持っているとします:
ethernet_adapter.PacketArrived += (s, e) =>
{
//long processing...
};
処理に時間がかかる場合があり、処理の途中で別のパケットが到着しました。次に何が起こるか: 処理が完了してから別のイベントが発生するか、新しいイベントがすぐに新しいスレッドで発生するのでしょうか?
これは同期操作である可能性があります。別のスレッドで発生する唯一の方法は、イベントを発生させるオブジェクトが別のスレッドで発生するか、ハンドラーで発生する場合です。これを行う方法は多数ありますが、System.Threading.Tasks.Task
.NET 4 を使用している場合は、一般的に を使用することをお勧めします。
アプリケーションの動作を慎重に検討してください。新しいスレッドで各パケットを処理するだけでは、パケットが順不同で処理される可能性があります。それらをキューに入れ、その時点でバックグラウンド スレッドに処理させることができます。または、何もする必要がない場合もあります。
想定してはいけません。ethernet_adapter
(オブジェクトの)タイプによってイベントがどのように発生するかによって、それは何でもかまいません。
同期操作の場合、現在の操作が進行中になるまで新しいイベントは発生しません。
非同期操作の場合、新しいイベントがすぐに発生します。
おそらくあなたのethernet_adapter
クラスにはメソッドがあります:
protected virtual void OnPacketArrived(PacketArrivedEventArgs e)
{
EventHandler<PacketArrivedEventArgs> handler = this.PacketArrived;
if (handler != null)
{
handler(this, e);
}
}
そのため、同期サブスクライバーの処理が長いと(例のように)、すべてのサブスクライバーに対する内部列挙がブロックされます。しかし!ifが毎回別のスレッドで呼び出すOnPacketArrived
場合は、後続の呼び出しをブロックしない可能性があります。そのため、2 つの同時の長い処理が発生します。ethernet_adapter
例として、Socket
実装を見てみましょう。これは非同期メソッドであり、IOCP スレッドで完了コールバックが呼び出されますThreadPool
。
次のように、タスク全体を ThreadPool でキューに入れることができます。
ethernet_adapter.PacketArrived += (s, e) =>
{
ThreadPool.QueueUserWorkItem("long processing item");
};
または、スレッドごとにタスク(.net 4.0)を作成できます。