3

私のアプリケーションでは、複数の異なるキューをリッスンし、キューで受信した着信メッセージを逆シリアル化/ディスパッチする必要があります。

実際、これを実現するために私が行っているのは、各QueueConnectorオブジェクトが構築時に新しいスレッドを作成し、queue.Receive()へのブロッキング呼び出しで無限ループを実行して、以下のコードで公開されているキュー内の次のメッセージを受信することです。

// Instantiate message pump thread
msmqPumpThread = new Thread(() => while (true)
{
   // Blocking call (infinite timeout)
   // Wait for a new message to come in queue and get it
   var message = queue.Receive();

   // Deserialize/Dispatch message
   DeserializeAndDispatchMessage(message);
}).Start();

この「メッセージポンプ」を、新しいスレッドで無限ループを通過する代わりに、タスクを使用して置き換えることができるかどうかを知りたいです。

メッセージ受信部分(以下を参照)用にすでにタスクを作成しましたが、メッセージポンプに使用する方法がわかりません(同じタスクを何度も何度も繰り返して、継続して、無限ループを置き換えることができますか?上記のコードのように別のスレッド?)

Task<Message> GetMessageFromQueueAsync()
{
    var tcs = new TaskCompletionSource<Message>();

    ReceiveCompletedEventHandler receiveCompletedHandler = null;

    receiveCompletedHandler = (s, e) =>
    {
       queue.ReceiveCompleted -= receiveCompletedHandler;
       tcs.SetResult(e.Message);
    };

    queue.BeginReceive();

    return tcs.Task;
}

このコンテキストで別のスレッド(ブロッキング呼び出し=>ブロッキングスレッドを使用)で無限ループの代わりにタスクを使用することで何かを得ることができますか?はいの場合、それを適切に行う方法は?

このアプリケーションには多くのQueueConnectorオブジェクトがなく、(おそらく最大10個のコネクタ)がないことに注意してください。つまり、最初のソリューションでは最大10個のスレッドがあるため、ここではメモリフットプリント/パフォーマンス開始スレッドは問題になりません。私はむしろスケジューリングパフォーマンス/CPU使用率について考えていました。違いはありますか?

4

1 に答える 1

0

一般に、スレッド数が少ない場合、非同期コードではオーバーヘッドが増加し、スループットが低下します。ノンブロッキング コードは、スレッド数が非常に多く、a) スタックによる大量のメモリの浪費、および b) コンテキスト スイッチが発生する場合に最も役立ちます。ただし、より多くの割り当て、より多くの間接化、およびより多くのユーザーカーネル遷移のために、顕著なオーバーヘッドがあります。

スレッド数が少ない (< 100) 場合は、おそらく心配する必要はありません。保守しやすく、バグに強く、シンプルなコードを書くことに集中してください。スレッドを使用します。

于 2012-07-05T20:12:42.113 に答える