当且仅当收到所有元素时,TransformBlock<TInput,TOutput>.TryReceiveAll(IList<TOutput>) 会返回 true 吗?

Posted

技术标签:

【中文标题】当且仅当收到所有元素时,TransformBlock<TInput,TOutput>.TryReceiveAll(IList<TOutput>) 会返回 true 吗?【英文标题】:Will TransformBlock<TInput,TOutput>.TryReceiveAll(IList<TOutput>) return true when if and only if all the element(s) received? 【发布时间】:2021-04-20 04:25:27 【问题描述】:

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

【问题讨论】:

问题的标题有点混乱,围绕着“当且仅当”这些词。老实说,我无法确切地告诉您您想知道什么。您能否编辑问题并消除标题中的歧义? 【参考方案1】:

让我们看看文档

TransformBlock&lt;TInput,TOutput&gt;.TryReceiveAll(IList&lt;TOutput&gt;) Method

退货

true 如果可以收到一件或多件物品;否则,false

如果它收到至少 1 item

,它会说它返回 true

让我们确保:

...

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;

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

当且仅当所有元素都收到时它才返回 true 吗?

我想这个问题的答案围绕着你所归类为 all...

内部缓冲等待调度(排队)的内容和管道中的内容可能是两种完全不同的东西。 TryReceiveAll 只会返回排队的项目。尚未排队(ergo 不可用)或以其他方式滞留在其他区块(您可能会认为全部)的项目不会被归类为已收到。

例如,您的整个管道中可能有 10 个项目正在运行,只有 2 个已到达转换块并等待调度。 TryReceiveAll 将返回这 2 个可用项目,并返回 true。

【讨论】:

谢谢,我该怎么办,当我需要等待收到的所有元素时,顺便说一句,微软需要将 TryReceiveAll 重命名为 TryReceiveAny...... @Fuqin 这取决于你在做什么,你可以等待transformblock.Completion 在你对变换块本身发出@​​987654331@ 信号后,或者已经配置为传递完成状态的高块沿着 @Fuqin 对不起,我刚刚意识到,CompletionTryRecieveAll 不会做你想做的,TansformBlock 永远不会满足等待完成的条件。您需要将CompleteOutputAvailableAsync 结合使用,Theodor Zoulias 在***.com/a/62410007/1612975 中给出了一个很好的例子。在所有条件相同的情况下,管道应该真正通过管道而不是阻塞转储【参考方案2】:

在我挖掘了一些源代码cmets之后, 我找到了解决这个问题的线索。 栈溢出老是丢图,所以贴了两个源码cmets 第一:

//
// 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);

因此,我认为我们可以编写这个 can receiveAllMessage

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

【讨论】:

以上是关于当且仅当收到所有元素时,TransformBlock<TInput,TOutput>.TryReceiveAll(IList<TOutput>) 会返回 true 吗?的主要内容,如果未能解决你的问题,请参考以下文章

当且仅当它在 React Native 中返回 null 时,如何使函数再次运行?

甲骨文:SQL;当且仅当一列更改时选择不同的记录

当且仅当区域在 Emacs 中处于活动状态时,标记是不是处于活动状态?

当且仅当 ContactsContract.Contacts.CONTENT_URI 更改时,ContentObserver 应该调用

当且仅当有新的提交时,如何在一天中的特定时间构建 XCode 机器人?

欧拉回路