当且仅当收到所有元素时,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<TInput,TOutput>.TryReceiveAll(IList<TOutput>) 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 对不起,我刚刚意识到,Completion
和TryRecieveAll
不会做你想做的,TansformBlock 永远不会满足等待完成的条件。您需要将Complete
与OutputAvailableAsync
结合使用,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 时,如何使函数再次运行?
当且仅当区域在 Emacs 中处于活动状态时,标记是不是处于活动状态?
当且仅当 ContactsContract.Contacts.CONTENT_URI 更改时,ContentObserver 应该调用