dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.56k stars 4.54k forks source link

BufferBlock with non-zero count and no consumers never completes if Canceled after Complete() #27357

Open congyiwu opened 5 years ago

congyiwu commented 5 years ago

Here's a minimal repro w/ .NET Core 2.1:

            var cts = new CancellationTokenSource();
            var b = new BufferBlock<int>(new ExecutionDataflowBlockOptions() { CancellationToken = cts.Token });

            Console.WriteLine($"Post {await b.SendAsync(1)}");
            b.Complete();

            Thread.Sleep(1000);
            cts.Cancel();

            Console.WriteLine($"Count {b.Count}");
            await b.Completion; // Hangs

I assumed [1] that canceling a BufferBlock would guarantee completion, but this doesn't appear to be the case:

Is this behavior expected? If so, is there a better way to "completely" cancel a BufferBlock more or less immediately?

In my actual product code, I have a BufferBlock src linked to an ActionBlock tgt. Sometimes tgt completes/faults before src. When that happens, I cancel src and wait for src.Completion, which hangs. I could simply stop waiting for src.Completion if that's the right thing to do.

It seems like the only consequence would be a memory leak while the VS debugger is attached (#30582), which is OK.

[1] I couldn't find any documentation that contradicted (or supported) my assumptions: https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.dataflow.bufferblock-1.completion?view=netcore-2.1 https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.dataflow.dataflowblockoptions.cancellationtoken?view=netcore-2.1

congyiwu commented 5 years ago

BTW @lferrao, I think this is the same issue as dotnet/runtime#26989, which you filed. It's possible that your issue only repros in the debugger because there's a slightly longer delay? I aws able to repro my issue w/ a release build outside of VS.

lfr commented 5 years ago

Thanks @congyiwu, that makes sense, I'll keep an eye open for this one as well.