本文介绍了避免使用 ActionBlock<TInput>.Post 当 PostDataflowBlockOptions.BoundedCapacity 不是默认值时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我听说如果使用 Post 方法而不是 ActionBlockSendAsync 方法,可能会丢失信息对象,当您决定使用它的 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 方法尝试同步发布项目并返回 truefalse,具体取决于关于区块是否接受该项目.不接受项目的原因:

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:

  1. 块被标记为完成(通过调用它的 Complete 方法).
  2. 块已完成,无论成功还是失败(其 Completion.IsCompleted 属性返回 true.
  3. 该块具有有界容量(选项 BoundedCapacity != -1),并且其缓冲区当前已满.

SendAsync 方法尝试异步发布项目并返回 Task.此任务将始终完成,除非该块具有有限容量,其缓冲区当前已满,并且当前未完成或标记为已完成.这是 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:

  1. 块在调用 SendAsync 之前或在等待期间被标记为已完成.
  2. 块在调用 SendAsync 之前完成,或者在等待期间由于异常,或者因为它的 Fault 方法被调用.
  1. The block was marked as completed either before calling the SendAsync, or during the awaiting.
  2. The block was completed either before calling the SendAsync, or during the awaiting as a result of an exception, or because its Fault method was invoked.

所以 PostSendAsync 之间的区别在于点 (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 可以看作是一个等待发生的错误,当一段时间后块被重新配置为有界时,以解决新发现的相关问题内存使用过多.

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

这篇关于避免使用 ActionBlock<TInput>.Post 当 PostDataflowBlockOptions.BoundedCapacity 不是默认值时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 17:13