如果PostDataflowBlockOptions.BoundedCapacity不是默认值,是否避免使用ActionBlock< TInput> .Post? [英] Avoiding use of ActionBlock<TInput>.Post when PostDataflowBlockOptions.BoundedCapacity is not the default value?
问题描述
我听说如果您使用 Post
方法而不是 SendAsync
方法会丢失信息。 ActionBlock< T>
对象,当您决定使用它的 BoundedCapacity
属性时。
I've heard that you can lose information if you use the Post
method instead of the SendAsync
method of an ActionBlock<T>
object, when you decide to utilize it's BoundedCapacity
property.
有人可以解释为什么会这样吗?
Could someone please explain why that is so?
推荐答案
Post
方法尝试同步发布项目,并返回 true
或 false
,具体取决于块是否接受了该项目或不。不接受项目的原因:
The Post
method attempts to post an item synchronously and returns true
or false
, depending on whether the block accepted the item or not. Reasons to not accept an item:
- 将该区块标记为已完成(通过调用其
Complete
方法)。 - 该块已成功完成或未成功完成(其
Completion.IsCompleted
属性返回true
)。 - 该块具有有限的容量(选项
BoundedCapacity!= -1
),并且其缓冲区当前已满。
- The block is marked as completed (by calling its
Complete
method). - The block is completed, either successfully or unsuccessfully (its
Completion.IsCompleted
property returnstrue
). - The block has a bounded capacity (option
BoundedCapacity != -1
), and its buffer is currently full.
SendAsync
方法尝试异步发布项目并返回任务< bool>
。除非块具有有限的容量,其缓冲区当前已满并且当前尚未完成或标记为已完成,否则该任务将始终完成。这是 SendAsync
唯一会异步表现的情况。等待任务后,任务的 bool
结果指示该块是否接受了该项目。不接受项目的原因:
The SendAsync
method attempts to post an item asynchronously and returns a Task<bool>
. This task will always be completed, unless the block has a bounded capacity, its buffer is currently full, and it's not currently completed or marked as completed. This is the only case that the SendAsync
will behave asynchronously. After awaiting the task, the bool
result of the task indicates whether the block accepted the item or not. Reasons to not accept an item:
- 在调用
SendAsync $ c之前,该块被标记为已完成$ c>,或者在等待期间。
- 该块在调用
SendAsync
之前完成,或者在等待期间完成或因为其 <
- The block was marked as completed either before calling the
SendAsync
, or during the awaiting. - The block was completed either before calling the
SendAsync
, or during the awaiting as a result of an exception, or because itsFault
method was invoked.
因此调用了code> Fault 方法。 c $ c> Post 和 SendAsync
是重点(3)。在具有完整缓冲区的有限容量块的情况下,它们的行为有所不同。在这种情况下, Post
立即拒绝该项目,而 SendAsync
将在缓冲区再次具有可用空间时异步接受该项目。
So the difference between Post
and SendAsync
is the point (3). They behave differently in the case of a bounded-capacity block with a full buffer. In this case the Post
rejects immediately the item, while the SendAsync
will asynchronously accept it when the buffer has free space again.
在大多数情况下, SendAsync
的行为是可取的。使用 Post
代替 SendAsync
可以看作是一个等待发生的错误,一段时间后,将block重新配置为有界,以解决新发现的与过度使用内存有关的问题。
In most cases the behavior of SendAsync
is the desirable one. Using the Post
instead of the SendAsync
can be seen as a bug that is waiting to happen, when some time later the block is reconfigured as bounded, to solve newly discovered problems related with excessive memory usage.
不放弃这两种方法的返回值是一个好主意,因为返回 false
的值在大多数情况下表示错误。很少有人会想到并准备处理 false
结果。一些想法:
It is a good idea to not dismiss the return value of both methods, because a return value of false
indicates in most cases a bug. it is quite rare to expect and be ready to handle a false
result. Some ideas:
if (!block.Post(item)) throw new InvalidOperationException();
if (!await block.SendAsync(item)) throw new InvalidOperationException();
var accepted = block.Post(item); Debug.Assert(accepted);
var accepted = await block.SendAsync(item); Debug.Assert(accepted);
这篇关于如果PostDataflowBlockOptions.BoundedCapacity不是默认值,是否避免使用ActionBlock< TInput> .Post?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!