-2

メッセージを処理するクラスがあります:

public abstract class ProcessingBase {
    public bool IsBusy { get; set; }
    public Queue<CustomMessage> PendingMessages { get; private set; }
    public abstract MessageProcessingResult Process();
    ...

これまでに作成した処理モジュールでは、1 つはキューを使用してメッセージを処理し、ソケットを介してメッセージを送信し、もう 1 つは電子メールを送信します。これは個々の処理モジュールでは問題なく機能しますが、これら 2 つを連鎖させたいとしますか?

私は次のようなことができると思っていました:

public class ChainProcessor : ProcessingBase {
    public List<ProcessingBase> Processors { get; set; }
    public override MessageProcessingResult Process() {
                if (IsBusy)
                    return null;
                IsBusy = true;

                CustomMessage msg = null;
                this.ProcessedMessages = new List<CustomMessage>();

                // create clone of queue 
                var messagesToSend = new Queue<CustomMessage>(this.PendingMessages);
                this.PendingMessages.Clear();
                while (messagesToSend.Count > 0 && (msg = messagesToSend.Dequeue()) != null) {
                    foreach (var processor in this.Processors) {
                        // something with yield return?
                    }
                }

それは私が不安定な実際のチェーンです。理想的には、それらを一種の「波」で処理したいと思います。例えば:

Module 1 - Processed message A
Module 2 - Processed message A
Module 1 - Processed message B
Module 2 - Processed message B
Module 3 - Processed message A
Module 1 - Processed message C

各メッセージがチェーンを通過する場所で、メッセージが通過するときにメッセージが絶えず出入りします。これを行う最良の方法は何ですか?それとも、チェーン全体を介して各メッセージを順番に渡すことに制限されていますか?

すなわち (私がしたくないもの): モジュール 1 - 処理されたメッセージ A モジュール 2 - 処理されたメッセージ A モジュール 3 - 処理されたメッセージ A モジュール 1 - 処理されたメッセージ B モジュール 2 - 処理されたメッセージ B モジュール 3 - 処理されたメッセージ B モジュール 1 - 処理されたメッセージC

編集:私は、最初のプロセッサが「チェーン プロセッサ」に戻り、そのメッセージをモジュール 2 に渡し、おそらくチェーンがプロセッサ 1 で次のメッセージを開始できる何かを実行できることを望んでいました。

4

2 に答える 2

0

ConcurrentQueueあなたはスレッドセーフを探していてAutoResetEvent、魔女は眠っているスレッドを起こすことができます(例を見てください)。

各ワーカーは独自のスレッドで実行され (メイン スレッドに何らかの作業がある場合)、ジョブを実行して入力キューを空にした後、 を呼び出しますAutoResetEvent.WaitOne()。入力キューがアイテムでいっぱいになった場合は、AutoResetEvent.Set()を呼び出してプロセスを再開します。

最初のワーカーによって処理されたアイテムで 2 番目のキューを作成することにより、これら 2 つのワーカーを連鎖させることができます。最初のワーカーがメッセージを処理した後、項目を出力キューに追加して を呼び出しますAutoResetEvent.Set()

読んでよく考えてください。私はあなたの状況を知りません。そのため、ニーズに合わせてプロセスを最適化できます。

幸運を。;-)

于 2012-10-25T21:42:31.777 に答える
0

私はあなたが使用できると思います

   BlockingCollection<CustomMessage>

モジュールごとに。その後、複数のスレッドを作成して各コレクションから読み取り、モジュールの処理作業を行うことができます。その後、次のモジュールのキューに入れます。

複数のスレッドを作成することで、並行して作業できます。BlockingCollection は、スレッドセーフで、高速で、ブロッキングです。とても便利。http://msdn.microsoft.com/en-us/library/dd267312.aspxを参照してください。

于 2012-07-04T15:32:42.680 に答える