我正在使用BufferBlock
实现Producer-Consumer。代码运行良好。
static async Task Produce(ITargetBlock<int> queue)
{
try
{
// Post messages to the block asynchronously.
for (int i = 0; i < 100; i++)
{
Console.WriteLine("Sending: {0}", i);
await queue.SendAsync(i);
}
}
finally
{
queue.Complete();
}
}
static async Task Consume(ISourceBlock<int> queue)
{
// Read messages from the block asynchronously.
while (await queue.OutputAvailableAsync())
{
int value = await queue.ReceiveAsync();
Console.WriteLine("Receiving: {0}", value);
}
}
static void Main(string[] args)
{
// Create a BufferBlock<int> object.
var queue = new BufferBlock<int>();
try
{
var produce = Produce(queue);
var consume = Consume(queue);
Task.WaitAll(produce, consume, queue.Completion);
}
catch (Exception exception)
{
Console.WriteLine("An exception was thrown: {0}", exception.Message);
Console.WriteLine("Terminating...");
}
}
现在我有一个限制问题,我希望消费者的最大并发数是4.我想使用SemaphoreSlim
机器人不知道如何应用它。
注意:这是一个并发调度问题,而不是并行问题。
答案 0 :(得分:3)
如果您想要的是一次只能消耗一定数量的金额,您可以多次拨打TryRecieve
,直到它为空,或达到金额。这是一个处理它的扩展方法:
public static bool TryReceive<T>(this BufferBlock<T> bufferBlock, int count, out IList<T> items)
{
items = new List<T>();
for (var i = 0; i < count; i++)
{
T item;
if (bufferBlock.TryReceive(out item))
{
items.Add(item);
}
else
{
break;
}
}
return items.Any();
}
所以消费者变成了:
static async Task Consume(BufferBlock<int> queue)
{
// Read messages from the block asynchronously.
while (await queue.OutputAvailableAsync())
{
IList<int> values;
queue.TryReceive(4, out values);
Console.WriteLine("Receiving: {0}", string.Join(", ", values));
}
}