gpt4 book ai didi

c# - BufferBlock 在 TryReceiveAll 之后与 OutputAvailableAsync 死锁

转载 作者:IT王子 更新时间:2023-10-29 04:39:31 24 4
gpt4 key购买 nike

在处理 an answer 时至 this question ,我写了这个片段:

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 毫秒将项目发送到缓冲区,而消费者应清除缓冲区中的所有项目并异步等待更多项目出现。

实际发生的是生产者清除所有项目一次,然后再也不会超出 OutputAvailableAsync。如果我将消费者切换为一件一件地移除元素,它会按异常(exception)情况工作:

while (await buffer.OutputAvailableAsync())
{
object item;
while (buffer.TryReceive(out item)) ;
}

我是不是误会了什么?如果不是,问题是什么?

最佳答案

这是 SourceCore 中的一个错误,被 BufferBlock 内部使用。它的 TryReceiveAll 方法不会打开 _enableOffering bool 数据成员,而 TryReceive 会。这导致从 OutputAvailableAsync 返回的任务永远不会完成。

这是一个最小的复制:

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

我刚刚用 this pull request 在 .Net 核心存储库中修复了它.希望修复程序很快就会出现在 nuget 包中。

关于c# - BufferBlock 在 TryReceiveAll 之后与 OutputAvailableAsync 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25339029/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com