Это одна из тех вещей, которую намного легче понять, как только вы это сделаете.
Для потребителя-производителя давайте два объекта: Производитель и Потребитель. Они оба имеют общую очередь, которую им дают при создании, поэтому они могут писать между ними.
Добавление в продюсере-потребителя довольно знакомо, только с CompleteAdding немного по-другому:
public class Producer{
private BlockingCollection<string> _queue;
public Producer(BlockingCollection<string> queue){_queue = queue;}
//a method to do something
public MakeStuff()
{
for(var i=0;i<Int.MaxValue;i++)
{
_queue.Add("a string!");
}
_queue.CompleteAdding();
}
}
Потребитель, похоже, не имеет смысла - пока вы не поймете, что foreach не прекратит зацикливание, пока очередь не закончит добавление. До тех пор, если нет никаких предметов, он просто уснет. И поскольку это один и тот же экземпляр коллекции у производителя и потребителя, вы можете заставить потребителя ТОЛЬКО запускать циклы, когда есть какие-то дела, и вам не придется беспокоиться о его остановке, перезапуске и т. Д.
public class Consumer()
{
private BlockingCollection<string> _queue;
public Consumer(BlockingCollection<string> queue)
{
_queue = queue;
}
public void WriteStuffToFile()
{
//we'll hold until our queue is done. If we get stuff in the queue, we'll start processing it then
foreach(var s in _queue.GetConsumingEnumerable())
{
WriteToFile(s);
}
}
}
Таким образом, вы соединяете их вместе, используя коллекцию.
var queue = new BlockingCollection<string>();
var producer = new Producer(queue);
var consumer = new Consumer(queue);
producer.MakeStuff();
consumer.WriteStuffToFile();