【发布时间】:2020-08-19 01:19:40
【问题描述】:
我有一个经典的生产者消费者问题,其中多个用户可以同时将数据发布到 Web API 方法(api/test),这会触发 IO 密集型 long异步运行操作。我使用链接到BufferBlock 的ActionBlock 将并发请求的数量限制为5。
Producer 类被注册为一个单例,目标是允许所有对 api/test 的调用进入这个队列。这意味着完成块之类的事情不是一种选择。
等待控制器完成我启动的工作的最有效方法是什么?
Web API 控制器:
[Route("api/test")]
[ApiController]
public class TestController : ControllerBase
{
private Producer producer;
public TestController(Producer producer)
{
this.producer = producer;
}
[HttpGet]
public async Task<string[]> Values()
{
for (int i = 1; i <= 10; i++)
{
await this.producer.AddAsync(1);
}
// i've added my work to the queue, elegant completion required
return new string[] { "value1", "value2" };
}
}
生产者/消费者实现:
public class Producer
{
private BufferBlock<int> queue;
private ActionBlock<int> consumer;
public List<int> results = new List<int>();
private void InitializeChain()
{
queue = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 5, });
var consumerOptions = new ExecutionDataflowBlockOptions { BoundedCapacity = 5, MaxDegreeOfParallelism = 5 };
consumer = new ActionBlock<int>(x =>
{
Thread.Sleep(5000);
Debug.WriteLine(x + " " + Thread.CurrentThread.ManagedThreadId);
results.Add(x);
}, consumerOptions);
queue.LinkTo(consumer, new DataflowLinkOptions { PropagateCompletion = true });
}
public async Task AddAsync(int data)
{
await queue.SendAsync(data);
}
public Producer()
{
this.InitializeChain();
}
}
【问题讨论】:
标签: c# async-await task-parallel-library tpl-dataflow