1

我想弄清楚如何创建一个多线程生产者/消费者程序,其中生产基于外部事件。

我已经建立了一个同步队列,它有 2 个线程循环,一个用于入队,一个用于出列并写入文件,具有经典模式:

Class SyncQueue  
{
    ...
    producerThread = new Thread(new ThreadStart(StartProducer));
    consumerThread = new Thread(new ThreadStart(StartConsumer));
    ...

    public void Start()
    {
        producerThread.Start();
        consumerThread.Start();
    }

    public void StartProducer()
    {
        while (!stop)
        { 
            //wait for an external event to happen 
            //Data data = eventHandler() : How to wait for an event and get?
            Enqueue(data);
        }
    }
}

另一方面,我在另一个类中有一个独立处理外部事件的方法。

public void OnExternalEvent()
{
    //event occured 
    //how to notify and send data to the producer thread?
}

我的问题不是关于生产者/消费者模式,而是关于整合其中的事件。

我发布的代码只是为了让我的问题更清楚,我在评论中添加了两个具体问题。

如果有人能告诉我该怎么做,我将不胜感激。我是 C# 新手,没有很强的事件处理背景。

4

2 回答 2

4

只需考虑为此使用 Rx (反应式扩展)。它们现代、灵活、方便、支持多线程,而且很简单。呵呵

通过使用IObservable<T>集合,您只需订阅它们并在有更改(发布)到它们时收到通知。

这是您发布数据的方式:

var subject = new Subject<string>();
subject.OnNext("Value");
subject.OnCompleted();

订阅方式如下:

subject.SubscribeOn(Scheduler.CurrentThread);  // this is for thread safety, for instance
subject.Subscribe(() => { /* some action */ });

哦,还有,所有这些都是线程安全的!

于 2013-11-12T13:44:25.953 回答
4

放弃您的自定义同步队列并使用BlockingCollection< T >

使用BlockingCollection,您没有单独的线程来控制队列。相反,您有一个队列,线程可以直接将项目入队或出队。数据结构本身处理任何并发问题,并在尝试出队时进行非忙等待。

有关示例,请参见https://stackoverflow.com/a/19848796/56778https://stackoverflow.com/a/19823345/56778,或者只是搜索一下。另外,请参阅我的简单多线程博客文章了解更多详细信息。

于 2013-11-12T14:20:01.373 回答