当且仅当所有元素都收到时,TransformBlock<TInput,TOutput>.TryReceiveAll(IList<TOutput>) return 才会为真?

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

之前贴的图片是官方定义的。但我仍然很困惑。当且仅当所有元素都收到时,return 是否为真?

让我们看看文档

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

Returns

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

它说它 returns true 如果它已经收到 至少 1

让我们确定一下:

...

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;

是的,文档是正确的...

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

我想这个问题的答案围绕着你 class 作为 all...

内部缓冲等待调度(排队)的内容和您的管道中的内容可能是 2 个完全不同的东西。 TryReceiveAll 只会 return 排队的项目。未排队(因此不可用)或以其他方式滞留在其他区块(您可能认为 all)的项目未按收到的方式 classed。

例如,您的整个管道中可能有 10 个项目在运行中,只有 2 个项目已命中转换块并等待分派。 TryReceiveAll 将 return 这 2 个可用项目,并且 return 正确。

在我挖掘了一些源代码评论之后, 我找到了解决这个问题的线索。 stack overflow老是丢图,所以贴了两个源码注释 第一:

//
// Summary:
//     Represents a dataflow block.
public interface IDataflowBlock
{
    //
    // Summary:
    //     Gets a Task that represents the asynchronous operation and completion of the
    //     dataflow block.
    //
    // Remarks:
    //     A dataflow block is considered completed when it is not currently processing
    //     a message and **when it has guaranteed that it will not process any more messages.**
    //     The returned Task will transition to a completed state when the associated block
    //     has completed. It will transition to the RanToCompletion state when the block
    //     completes its processing successfully according to the dataflow block’s defined
    //     semantics, it will transition to the Faulted state when the dataflow block has
    //     completed processing prematurely due to an unhandled exception, and it will transition
    //     to the Canceled state when the dataflow block has completed processing prematurely
    //     due to receiving a cancellation request. If the task completes in the Faulted
    //     state, its Exception property will return an System.AggregateException containing

    //     the one or more exceptions that caused the block to fail.
    Task Completion { get; }

第二个:

//
// Summary:
//     Attempts to synchronously receive an item from the System.Threading.Tasks.Dataflow.ISourceBlock`1.
//
// Parameters:
//   source:
//     The source from which to receive.
//
//   item:
//     The item received from the source.
//
// Returns:
//     true if an item could be received; otherwise, false.
//
// Remarks:
//     This method does not wait until the source has an item to provide. It will return
//     whether or not an element was available.
public static bool TryReceive<TOutput>(this IReceivableSourceBlock<TOutput> source, out TOutput item);

因此,我认为我们可以编写代码来接收所有消息

      block.Complete();
await block.Completion.Configuration(false);
block.TryReceiveAll(out items);