c# - TPL 数据流,Post() 和 SendAsync() 之间的功能区别是什么?

标签 c# concurrency task-parallel-library message-passing tpl-dataflow

我对通过 Post() 或 SendAsync() 发送项目之间的区别感到困惑。我的理解是,在所有情况下,一旦项目到达数据 block 的输入缓冲区,控制权就会返回到调用上下文,对吗?那我为什么需要 SendAsync?如果我的假设不正确,那么我想知道,相反,如果使用数据 block 的整个想法是建立一个并发和异步环境,为什么有人会使用 Post() 。

我当然理解技术上的区别在于 Post() 返回 bool 而 SendAsync 返回 bool 的可等待任务。但这有什么影响呢? bool 的返回(我的理解是确认该项目是否被放置在数据 block 的队列中)何时会被延迟?我了解 async/await 并发框架的一般概念,但在这里它没有多大意义,因为除了 bool 之外,对传入项所做的任何操作的结果永远不会返回给调用者,而是放在一个“出队”并转发到链接的数据 block 或丢弃。

发送元素时,这两种方法在性能上有什么区别吗?

最佳答案

要查看差异,您需要一种情况,其中 block 将推迟它们的消息。在这种情况下,Post 将立即返回 false,而 SendAsync 将返回一个 Task,它将在 block 决定如何处理消息。如果消息被接受,Task 将有一个 true 结果,否则一个 false 结果。

延迟情况的一个例子是非贪婪连接。一个更简单的示例是当您设置 BoundedCapacity 时:

[TestMethod]
public void Post_WhenNotFull_ReturnsTrue()
{
    var block = new BufferBlock<int>(new DataflowBlockOptions {BoundedCapacity = 1});

    var result = block.Post(13);

    Assert.IsTrue(result);
}

[TestMethod]
public void Post_WhenFull_ReturnsFalse()
{
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 });
    block.Post(13);

    var result = block.Post(13);

    Assert.IsFalse(result);
}

[TestMethod]
public void SendAsync_WhenNotFull_ReturnsCompleteTask()
{
    // This is an implementation detail; technically, SendAsync could return a task that would complete "quickly" instead of already being completed.
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 });

    var result = block.SendAsync(13);

    Assert.IsTrue(result.IsCompleted);
}

[TestMethod]
public void SendAsync_WhenFull_ReturnsIncompleteTask()
{
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 });
    block.Post(13);

    var result = block.SendAsync(13);

    Assert.IsFalse(result.IsCompleted);
}

[TestMethod]
public async Task SendAsync_BecomesNotFull_CompletesTaskWithTrueResult()
{
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 });
    block.Post(13);
    var task = block.SendAsync(13);

    block.Receive();

    var result = await task;
    Assert.IsTrue(result);
}

[TestMethod]
public async Task SendAsync_BecomesDecliningPermanently_CompletesTaskWithFalseResult()
{
    var block = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 });
    block.Post(13);
    var task = block.SendAsync(13);

    block.Complete();

    var result = await task;
    Assert.IsFalse(result);
}

关于c# - TPL 数据流,Post() 和 SendAsync() 之间的功能区别是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13599305/

相关文章:

c# - Environment.UserName 在 Windows 7、Windows 8.x 和 Windows 10 中会返回相同的结果吗?

c++11 - 控制台输出顺序减慢多线程程序

c# - Task.ContinueWith() 与 2 个任务?

c# - Thread.Interrupt 等效于任务 TPL

c# - 读取net core api 3.1中的AuthorizationFilterContext

c# - 将 UUID 转换为 OID,将 Java 代码转换为 C# - 这是如何工作的?

c# - 从 .net 同时调用两个 Matlab 函数

c# - TPL 数据流,替代 JoinBlock 限制?

c# - 如何安装/部署在 C#.net 中开发的 VSTO Excel 2010 插件?

php - 限制应用程序中每个组的用户数