c# – 一起使用BlockingCollection和TPL数据流时出现死锁
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 一起使用BlockingCollection和TPL数据流时出现死锁,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1877字,纯文字阅读大概需要3分钟。
内容图文
![c# – 一起使用BlockingCollection和TPL数据流时出现死锁](/upload/InfoBanner/zyjiaocheng/786/d36b926716a44fdb8550587eb410719e.jpg)
我写了一个复制问题的示例测试.这不是我的实际代码,我试着写一个小的repro.如果你将边界容量增加到迭代次数有效地给它没有边界,它就不会死锁,如果你把max parallelism放到像1这样的小数字,它就不会死锁.
同样,我知道下面的代码不是很好,但我实际发现的代码更大,难以理解.基本上,存在与远程资源的连接的阻塞对象池,并且流中的若干块使用了连接.
关于如何解决这个问题的任何想法?乍一看,它似乎是数据流的问题.当我打破看看线程时,我看到许多线程被阻塞在Add和0线程被阻塞. addBlocks出站队列中有几个项尚未传播到takeblock,因此它被卡住或死锁.
var blockingCollection = new BlockingCollection<int>(10000);
var takeBlock = new ActionBlock<int>((i) =>
{
int j = blockingCollection.Take();
}, new ExecutionDataflowBlockOptions()
{
MaxDegreeOfParallelism = 20,
SingleProducerConstrained = true
});
var addBlock = new TransformBlock<int, int>((i) =>
{
blockingCollection.Add(i);
return i;
}, new ExecutionDataflowBlockOptions()
{
MaxDegreeOfParallelism = 20
});
addBlock.LinkTo(takeBlock, new DataflowLinkOptions()
{
PropagateCompletion = true
});
for (int i = 0; i < 100000; i++)
{
addBlock.Post(i);
}
addBlock.Complete();
await addBlock.Completion;
await takeBlock.Completion;
解决方法:
TPL Dataflow并不适用于阻塞很多的代码,我认为这个问题源于此.
我无法弄清楚究竟发生了什么,但我认为解决方案是使用非阻塞集合.方便的是,Dataflow以BufferBlock的形式为您提供了一个.有了它,您的代码将如下所示:
var bufferBlock = new BufferBlock<int>(
new DataflowBlockOptions { BoundedCapacity = 10000 });
var takeBlock = new ActionBlock<int>(
async i =>
{
int j = await bufferBlock.ReceiveAsync();
}, new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 20,
SingleProducerConstrained = true
});
var addBlock = new TransformBlock<int, int>(
async i =>
{
await bufferBlock.SendAsync(i);
return i;
}, new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 20
});
虽然我发现你的代码的整个设计是可疑的.如果要发送一些其他数据以及块的正常结果,请将该块的输出类型更改为包含该附加数据的类型.
内容总结
以上是互联网集市为您收集整理的c# – 一起使用BlockingCollection和TPL数据流时出现死锁全部内容,希望文章能够帮你解决c# – 一起使用BlockingCollection和TPL数据流时出现死锁所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。