Take/TryTake 和 Add/TryAdd 在阻塞 Collection 上的区别
Difference between Take/TryTake and Add/TryAdd on a Blocking Collection
我一直在努力了解 Blocking Collection,我遇到了 Take()
和 TryTake()
,还有 Add()
和 TryAdd()
我知道如果没有物品可以带走,Take()
会等到有物品被添加,与Add()
类似,如果collection已经达到最大限制,它将等到项目被删除。
根据Josheph Albahari's article on Parallel Programming
"Add and TryAdd may block if the collection size is bounded; Take and
TryTake block while the collection is empty."
因此 Take()
和 TryTake()
都在等待添加项目。那么,如果我们不提供任何超时或取消令牌,Take()
和 TryTake()
之间有什么区别,难道 TryTake()
return false
不应该直接而不等待吗? TryAdd()
?
也一样
TryTake
does not wait, it immediately returns false
if collection has nothing. Take
将等待一个项目。
试拍:
If the collection is empty, this method immediately returns false.
取:
A call to Take may block until an item is available to be removed.
Take
将通过抛出 InvalidOperationException
来表示队列完成。如果您将异常选项卡配置为抛出捕获的异常,这会使调试变得有点困难。
因此,我确实尝试使用TryTake
。事实证明 BlockingCollection<T>.Take
实际上确实使用了 TryTake
,但超时是无限的。所以与其这样写:
while (!queue.IsCompleted)
{
object obj;
try
{
obj = queue.Take();
}
catch (InvalidOperationException)
{
continue;
}
// Do something with obj.
}
您可以按如下方式使用TryTake
:
while (!queue.IsCompleted)
{
if (!queue.TryTake(out var obj, Timeout.InfiniteTimeSpan))
continue;
// Do something with obj.
}
使代码更简洁并且不会抛出 InvalidOperationException
。
我偶然发现了这个问题,我认为微软的这篇文档对弄清楚科学背后发生的事情非常有帮助。
If no item is present, maximum capacity on a bounded collection has been reached, or the timeout period has elapsed, then the TryAdd or TryTake operation returns false. This allows the thread to do some other useful work for a while and then try again later to either retrieve a new item or try to add the same item that could not be added previously.
How to Add and Take Items Individually from a BlockingCollection
我一直在努力了解 Blocking Collection,我遇到了 Take()
和 TryTake()
,还有 Add()
和 TryAdd()
我知道如果没有物品可以带走,Take()
会等到有物品被添加,与Add()
类似,如果collection已经达到最大限制,它将等到项目被删除。
根据Josheph Albahari's article on Parallel Programming
"Add and TryAdd may block if the collection size is bounded; Take and TryTake block while the collection is empty."
因此 Take()
和 TryTake()
都在等待添加项目。那么,如果我们不提供任何超时或取消令牌,Take()
和 TryTake()
之间有什么区别,难道 TryTake()
return false
不应该直接而不等待吗? TryAdd()
?
TryTake
does not wait, it immediately returns false
if collection has nothing. Take
将等待一个项目。
试拍:
If the collection is empty, this method immediately returns false.
取:
A call to Take may block until an item is available to be removed.
Take
将通过抛出 InvalidOperationException
来表示队列完成。如果您将异常选项卡配置为抛出捕获的异常,这会使调试变得有点困难。
因此,我确实尝试使用TryTake
。事实证明 BlockingCollection<T>.Take
实际上确实使用了 TryTake
,但超时是无限的。所以与其这样写:
while (!queue.IsCompleted)
{
object obj;
try
{
obj = queue.Take();
}
catch (InvalidOperationException)
{
continue;
}
// Do something with obj.
}
您可以按如下方式使用TryTake
:
while (!queue.IsCompleted)
{
if (!queue.TryTake(out var obj, Timeout.InfiniteTimeSpan))
continue;
// Do something with obj.
}
使代码更简洁并且不会抛出 InvalidOperationException
。
我偶然发现了这个问题,我认为微软的这篇文档对弄清楚科学背后发生的事情非常有帮助。
If no item is present, maximum capacity on a bounded collection has been reached, or the timeout period has elapsed, then the TryAdd or TryTake operation returns false. This allows the thread to do some other useful work for a while and then try again later to either retrieve a new item or try to add the same item that could not be added previously.
How to Add and Take Items Individually from a BlockingCollection