Search code examples
c#task-parallel-librarytpl-dataflow

Will TransformBlock<TInput,TOutput>.TryReceiveAll(IList<TOutput>) return true when if and only if all the element(s) received?


Screenshot from the documentation of TryReceiveAll method

Previously pasted picture is the official definition. But I am still confused. Does it return true if and only if all the element(s) received?


Solution

  • Let's look at the documentation

    TransformBlock<TInput,TOutput>.TryReceiveAll(IList<TOutput>) Method

    Returns

    true if one or more items could be received; otherwise, false.

    It says it returns true if it has received at least 1 item

    Let's make sure:

    ...
    
    while (_messages.TryDequeue(out item)) 
        tmpList.Add(item);
    
    countReceived = tmpList.Count;
    
    ...
    
    if (countReceived > 0)
    {
        // Notify the owner block that our count has decreased
        if (_itemsRemovedAction != null)
        {
            int count = _itemCountingFunc != null ? _itemCountingFunc(_owningSource, default(TOutput)!, items) : countReceived;
            _itemsRemovedAction(_owningSource, count);
        }
        return true;
    }
    else return false;
    

    Yup, documentation is correct...

    Does it return true if and only if all the element(s) received?

    I guess the answer to this revolves around what you class as all...

    What is buffered internally awaiting dispatch (queued), and what is in your pipeline may be 2 completely different things. TryReceiveAll will only return queued items. Items that haven't been queued (ergo not available) or otherwise held-up in other blocks (which you may consider all) is not classed as received.

    For instance, you could have 10 items in flight in your entire pipeline, only 2 has hit the transform block and awaiting dispatch. TryReceiveAll will return those 2 available items, and return true.