[英]Dataflow (Task Parallel Library) and async await
假设我使用.NET中的Dataflow块。 据说“这个数据流模型促进了基于演员的编程”,这是我想要在这里得到的。
但是,如果我处理来自BufferBlock<T>
的消息以及消息的处理器中的消息,我决定使用async
/ await
,这会将执行分配给当前的脚本和等待任务的工作线程。
有没有办法阻止演员/消息处理器内的并发执行?
如果等待的任务使用具有本机回调的非阻塞IO操作执行,那就没问题。 但我真的想确保任何.NET代码只能同步执行。
这在很大程度上取决于您将如何处理这些消息。
如果您使用的ActionBlock
与async
action
,不设置其MaxDegreeOfParallelism
(这意味着使用的默认值1),并将其链接到BufferBlock
,那么action
将在一次执行了一个消息,不会有并行。
如果您使用如下循环手动处理消息:
while (await bufferBlock.OutputAvailableAsync())
{
var message = await bufferBlock.ReceiveAsync();
await ProcessMessageAsync(message);
}
然后,消息也将一次处理一个。
但在这两种情况下,并不意味着消息将由单个线程处理。 它可以由多个线程处理,但不能并行处理。 这是因为在await
之后,执行可以在与暂停的位置不同的线程上恢复。
如果您使用其他方式处理消息(例如,使用上面的循环,但在ProcessMessageAsync()
之前省略await
),则可以同时处理多个消息。
你误解了await
做什么。 它不会分叉任何东西,它只是等待已经异步操作的结果。
使用async
关键字标记的方法不会自动变为异步。 只有在async
方法中遇到异步操作时才会异步执行。 async
关键字只是告诉编译器在异步操作完成后应该继续执行的位置。
等待时没有ThreadPool线程被浪费或受到伤害,所以你不应该试图限制,阻止或避免这种情况。 事实上,在使用异步操作时,您可以获得更好的可伸缩性,因为TPL Dataflow使用的ThreadPool线程不会阻止等待长时间运行的异步操作,如I / O或Web服务调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.