TPL Dataflow, whats the functional difference between Post() and SendAsync()?

前端 未结 2 840
半阙折子戏
半阙折子戏 2020-12-02 20:04

I am confused about the difference between sending items through Post() or SendAsync(). My understanding is that in all cases once an item reached the input buffer of a data

2条回答
  •  没有蜡笔的小新
    2020-12-02 20:22

    To see the difference, you need a situation where blocks will postpone their messages. In this case, Post will return false immediately, whereas SendAsync will return a Task that will be completed when the block decides what to do with the message. The Task will have a true result if the message is accepted, and a false result if not.

    One example of a postponing situation is a non-greedy join. A simpler example is when you set BoundedCapacity:

    [TestMethod]
    public void Post_WhenNotFull_ReturnsTrue()
    {
        var block = new BufferBlock(new DataflowBlockOptions {BoundedCapacity = 1});
    
        var result = block.Post(13);
    
        Assert.IsTrue(result);
    }
    
    [TestMethod]
    public void Post_WhenFull_ReturnsFalse()
    {
        var block = new BufferBlock(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(new DataflowBlockOptions { BoundedCapacity = 1 });
    
        var result = block.SendAsync(13);
    
        Assert.IsTrue(result.IsCompleted);
    }
    
    [TestMethod]
    public void SendAsync_WhenFull_ReturnsIncompleteTask()
    {
        var block = new BufferBlock(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(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(new DataflowBlockOptions { BoundedCapacity = 1 });
        block.Post(13);
        var task = block.SendAsync(13);
    
        block.Complete();
    
        var result = await task;
        Assert.IsFalse(result);
    }
    

提交回复
热议问题