3

私は現在、MSMQから次のように読んでいます(簡潔にするために簡略化):

public void Start()
{
    this.queue.ReceiveCompleted += this.ReceiveCompleted;
    this.queue.BeginReceive();
}

void ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
    this.queue.EndReceive(e.AsyncResult);

    try
    {
        var m = e.Message;
        m.Formatter = this.formatter;

        this.Handle(m.Body);
    }
    finally
    {
        this.queue.BeginReceive();
    }
}

ただし、これではメッセージをシリアルに処理することしかできません。並列メッセージ処理を可能にするためにこのコードを変更するにはどうすればよいですか?

から上に移動できることはわかっthis.queue.BeginReceive();ていますが、メッセージの数だけスレッドが生成されるのを防ぐにはどうすればよいですか?スレッドプールをフラッディングしないように、並列処理のレベルを適切に制御するにはどうすればよいですか?このための組み込みのメカニズムはありますか、それとも自分のマネージャーを作成する必要がありますか?finallyReceiveCompleted

編集:私の目的は、メッセージをより速く処理することです。メッセージの処理にはサードパーティへの非同期呼び出しが含まれるため、現在、私の実装はキューを通過するのに多くの時間を浪費しています。

ありがとう

4

2 に答える 2

4

キュー リーダーのインスタンスをさらにホストする方が簡単だと思います。その後、必要に応じてインスタンスをさらにデプロイ/デプロイ解除することで、迅速にスケールアップおよびスケールダウンできます。

また、スケーリングは開発の問題ではなく、管理の問題になります。

于 2013-01-10T11:29:39.007 に答える
0

「Producer Consumer Pattern」を使用できます...

.NET 4以降Concurrentには、スレッドセーフで「ほとんどロックフリー」で実装されたコレクションがあります(したがって、マルチスレッドでうまく機能します)...

TPL と組み合わせて使用​​すると、スレッドBlockingCollectionプールの枯渇などをあまり心配することなく、目的を達成できます...行this.Handle(m.Body); を次のように変更して、実際の作業を実行するMyBlockingCollection.Add(m.Body);「消費者スレッド」をスピンアップするだけです (つまり、 on を呼び出します)。たとえば、呼び出して取得する次のアイテム) ...基本的なサンプルについては上記のリンクを参照してください...MyBlockingCollectionthis.HandleMyBlockingCollectionTryTake

于 2013-01-10T11:20:20.330 に答える