当且仅当所有元素都收到时,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);
之前贴的图片是官方定义的。但我仍然很困惑。当且仅当所有元素都收到时,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);