基于事件的多线程生产者 - 消费者?

时间:2013-11-12 13:20:08

标签: c# multithreading events producer-consumer

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

我已经构建了一个具有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#的新手,没有强大的事件处理背景。

2 个答案:

答案 0 :(得分:4)

考虑使用Rx (Reactive extensions)。它们现代,灵活,方便,支持多线程,简单而言,只是很酷。他他

使用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 */ });

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

答案 1 :(得分:4)

抛弃自定义同步队列并使用BlockingCollection< T >

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

有关示例,请参阅https://stackoverflow.com/a/19848796/56778https://stackoverflow.com/a/19823345/56778,或者只是搜索一下。另外,请参阅我的Simple Multithreading blog post了解更多细节。