BufferBlock僵局OutputAvailableAsync后TryReceiveAll [英] BufferBlock deadlock with OutputAvailableAsync after TryReceiveAll
问题描述
而努力 到的这个问题,我写了这个片断:
While working on an answer to this question, I wrote this snippet:
var buffer = new BufferBlock<object>();
var producer = Task.Run(async () =>
{
while (true)
{
await Task.Delay(TimeSpan.FromMilliseconds(100));
buffer.Post(null);
Console.WriteLine("Post " + buffer.Count);
}
});
var consumer = Task.Run(async () =>
{
while (await buffer.OutputAvailableAsync())
{
IList<object> items;
buffer.TryReceiveAll(out items);
Console.WriteLine("TryReceiveAll " + buffer.Count);
}
});
await Task.WhenAll(consumer, producer);
生产企业应条目发布到缓冲区每100毫秒和消费者应清除所有项目从缓冲区和异步等待更多的项目出现。
The producer should post items to the buffer every 100 ms and the consumer should clear all items out of the buffer and asynchronously wait for more items to show up.
什么实际情况是,生产者清除所有项目一次,然后再也没有超越了 OutputAvailableAsync
。如果我转了消费者一个它的工作原理,以消除项目之一的除外:
What actually happens is that the producer clears all items once, and then never again moves beyond OutputAvailableAsync
. If I switch the consumer to remove items one by one it works as excepted:
while (await buffer.OutputAvailableAsync())
{
object item;
while (buffer.TryReceive(out item)) ;
}
我误解的东西吗?如果没有,是什么问题?
Am I misunderstanding something? If not, what is the problem?
推荐答案
这是 SourceCore
内部正在使用的 BufferBlock $的错误C $ C>。其
TryReceiveAll
方法不转动 _enableOffering
布尔数据成员上,而 TryReceive
一样。这导致从 OutputAvailableAsync
返回的任务从未完成。
This is a bug in SourceCore
being used internally by BufferBlock
. Its TryReceiveAll
method doesn't turn on the _enableOffering
boolean data member while TryReceive
does. That results in the task returned from OutputAvailableAsync
never completing.
下面是一个最小的重现:
Here's a minimal reproduce:
var buffer = new BufferBlock<object>();
buffer.Post(null);
IList<object> items;
buffer.TryReceiveAll(out items);
var outputAvailableAsync = buffer.OutputAvailableAsync();
buffer.Post(null);
await outputAvailableAsync; // Never completes
我刚刚固定它与这种拉动申请。净核心存储库。希望修复很快就发现自己在的NuGet包。
I've just fixed it in the .Net core repository with this pull request. Hopefully the fix finds itself in the nuget package soon.
这篇关于BufferBlock僵局OutputAvailableAsync后TryReceiveAll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!