5

私が持っているとします:

ethernet_adapter.PacketArrived += (s, e) => 
{
    //long processing...
};

処理に時間がかかる場合があり、処理の途中で別のパケットが到着しました。次に何が起こるか: 処理が完了してから別のイベントが発生するか、新しいイベントがすぐに新しいスレッドで発生するのでしょうか?

4

4 に答える 4

2

これは同期操作である可能性があります。別のスレッドで発生する唯一の方法は、イベントを発生させるオブジェクトが別のスレッドで発生するか、ハンドラーで発生する場合です。これを行う方法は多数ありますが、System.Threading.Tasks.Task.NET 4 を使用している場合は、一般的に を使用することをお勧めします。

アプリケーションの動作を慎重に検討してください。新しいスレッドで各パケットを処理するだけでは、パケットが順不同で処理される可能性があります。それらをキューに入れ、その時点でバックグラウンド スレッドに処理させることができます。または、何もする必要がない場合もあります。

于 2012-12-26T13:52:40.023 に答える
2

想定してはいけません。ethernet_adapter(オブジェクトの)タイプによってイベントがどのように発生するかによって、それは何でもかまいません。

同期操作の場合、現在の操作が進行中になるまで新しいイベントは発生しません。

非同期操作の場合、新しいイベントがすぐに発生します。

于 2012-12-26T14:05:14.483 に答える
0

おそらくあなたの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

于 2012-12-26T14:09:41.860 に答える
0

次のように、タスク全体を ThreadPool でキューに入れることができます。

ethernet_adapter.PacketArrived += (s, e) => 
{
ThreadPool.QueueUserWorkItem("long processing item");
};

または、スレッドごとにタスク(.net 4.0)を作成できます。

于 2012-12-26T13:54:20.307 に答える