繁体   English   中英

数据流(任务并行库)和异步等待

[英]Dataflow (Task Parallel Library) and async await

假设我使用.NET中的Dataflow块。 据说“这个数据流模型促进了基于演员的编程”,这是我想要在这里得到的。

但是,如果我处理来自BufferBlock<T>的消息以及消息的处理器中的消息,我决定使用async / await ,这会将执行分配给当前的脚本和等待任务的工作线程。

有没有办法阻止演员/消息处理器内的并发执行?

如果等待的任务使用具有本机回调的非阻塞IO操作执行,那就没问题。 但我真的想确保任何.NET代码只能同步执行。

这在很大程度上取决于您将如何处理这些消息。

如果您使用的ActionBlockasync 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM