c# - 当集合为空时,BlockingCollection TryTake 返回 false 而不是 block
问题描述
当BlockingCollection为空时,我从 BlockingCollection 的TryTake方法返回 false ,尽管预期的行为是阻塞直到集合填满。
请注意,集合没有上限(这应该影响 TryAdd 而不是 TryTake),并且为添加操作设置的 Timeout 尚未通过。
这是我对 BlockingCollection 对象的包装:
public T TryTake(int timeoutMiliseconds)
{
var result = default(T);
if (!_collection.TryTake(out result, timeoutMiliseconds))
{
throw new InvalidOperationException("Unable to get item from collection.");
}
return result;
}
有什么想法会导致这种情况吗?
我已经实现了生产者-消费者模式,基于这篇文章: SqlDataReader 的多线程处理 - 生产者/消费者设计模式
解决方案
我终于意识到,正如这篇SO 帖子TryTake
所展示的那样,由于集合已被清空,我得到了错误,并且我也将其标记为已完成(通过调用CompleteAdding()
集合上的方法)。
所以为了解决它,我在完成标志上添加了一个条件。
有人可以争辩说,当已完成标志为 false 时,它TryTake
永远不会返回false。我不确定这总是正确的,所以我更愿意在这种情况下抛出一个错误。
public T TryTake(int timeoutMiliseconds)
{
var result = default(T);
if (!_collection.TryTake(out result, timeoutMiliseconds)
&& !_collection.IsAddingCompleted)
{
throw new InvalidOperationException("Unable to get item from collection.");
}
return result;
}
请注意,将TryTake
电话放在第一位和IsAddingCompleted
第二位至关重要。否则,第一个条件可能会通过,然后您会立即阻止TryTake
。
推荐阅读
- winforms - 将 Win Form Text 输入转换为 PowerShell 中使用的变量
- linux - 如何使用现有环境变量通过 echo 命令写入 $BASH_ENV?
- google-app-engine - Google App Engine cron 作业失败且不重试
- java - 如何修复运行时异常(覆盖)
- docker - 使用 pyspark lib 构建 docker 映像时出现问题
- swift - 在用户默认值中存储 Firestore 时间戳
- c# - 是否可以从描述属性动态生成摘要
- matlab - 具有空字符串连接的 Datenum 行为
- java - 在spring boot中使用带有多个数据库的jdbi库
- android - Android - 选择图像时无法两次使用相同的 URI