BufferBlock僵局OutputAvailableAsync后TryReceiveAll [英] BufferBlock deadlock with OutputAvailableAsync after TryReceiveAll

查看:369
本文介绍了BufferBlock僵局OutputAvailableAsync后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 。其 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆