-2

我有一个处理消息的类:

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

在我迄今为止创建的处理模块中,一个使用队列来处理消息,通过套接字发送它们,另一个发送电子邮件。这适用于单个处理模块,但假设我想链接这两个?

我在想我可以做类似的事情:

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

我认为你可以使用

   BlockingCollection<CustomMessage>

对于每个模块。然后,您可以创建多个线程以从每个集合中读取并执行模块的处理工作。之后将其放入下一个模块的队列中。

通过创建多个线程,您可以并行工作。BlockingCollection 是线程安全的、快速的和阻塞的。很方便。请参阅http://msdn.microsoft.com/en-us/library/dd267312.aspx

于 2012-07-04T15:32:42.680 回答
0

您正在寻找线程安全ConcurrentQueue,并且AutoResetEvent女巫可以唤醒休眠线程(参见示例)。

每个工作人员都在自己的线程上运行(如果您有一些主线程工作),并且在完成工作并清空其输入队列后,调用AutoResetEvent.WaitOne(). 如果输入队列被某个项目填满,则调用AutoResetEvent.Set(),它会再次启动该过程。

您可以通过使用第一个工作人员处理的项目创建第二个队列来链接这两个工作人员。在第一个工作人员完成消息后,将项目添加到输出队列并调用AutoResetEvent.Set()

仔细阅读并三思而后行,我不知道您的情况,因此您可以根据需要优化流程。

祝你好运。;-)

于 2012-10-25T21:42:31.777 回答