Как передать данные из одного потока в три других потока?

Мне нужно написать приложение, состоящее из четырех потоков:

  1. поток генерирует некоторые данные (поток-производитель);
  2. поток получает данные из потока производителя и выполняет Action1(data);
  3. поток получает данные из потока производителя и выполняет Action2(data);
  4. поток получает данные из потока производителя и выполняет Action3(data);

Как передать одни и те же данные всем трем потребляющим потокам? Я ограничен библиотеками .NET 3.0, т. е. не могу использовать такие штуки, как ConcurrentQueues и так далее.


person Igor Sotnyk    schedule 23.09.2014    source источник
comment
Наследовать от потока все четыре раза. Расширьте производные с помощью свойств или сеттеров или даже в ctor, вы можете передать данные после завершения t1. Затем, после передачи возвращенных данных из t1 в производные, начинают их работу.   -  person icbytes    schedule 23.09.2014
comment
I can't use such things as ConcurrentQueues and so on. затем используйте стандартный словарь/очередь/список, но заблокируйте все операции чтения и записи   -  person L.B    schedule 23.09.2014
comment
@LB Это не так просто. Выполнение операции «Подождите, пока у вас не будет другого предмета, чтобы дать мне, а затем отдайте его мне» — это то, что BlockingCollection дает вам, что делает эту операцию довольно приятной. Для повторной реализации этого требуется больше, чем просто lock.   -  person Servy    schedule 23.09.2014


Ответы (1)


Один из вариантов заключается в том, чтобы ваш производитель просто запускал событие всякий раз, когда он производит данные, что позволяет вам иметь любое количество различных потребителей, которые подписываются на событие и ставят в очередь работу, которая будет выполняться на основе этих данных в потоке пула потоков.

public class Producer
{
    public event Action<Data> DataProduced;

    public void Produce()
    {
        while (true)
        {
            Thread.Sleep(1000);//placeholder for real work
            DataProduced(new Data());//populate with real data
        }
    }
}

Producer producer = new Producer();

producer.DataProduced += data => 
    ThreadPool.QueueUserWorkItem(_ => Consume1(data));
producer.DataProduced += data => 
    ThreadPool.QueueUserWorkItem(_ => Consume2(data));
producer.DataProduced += data => 
    ThreadPool.QueueUserWorkItem(_ => Consume3(data));

producer.Produce();
person Servy    schedule 23.09.2014