簡體   English   中英

使用BlockingCollection時出現死鎖 <T> 和TPL數據流一起

[英]Deadlocks when using BlockingCollection<T> and TPL dataflow together

我寫了一個復制問題的示例測試。 這不是我的實際代碼,我試着寫一個小的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
    });

雖然我發現你的代碼的整個設計是可疑的。 如果要發送一些其他數據以及塊的正常結果,請將該塊的輸出類型更改為包含該附加數據的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM