-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
After upgrading to System.Threading.Tasks.Dataflow 8.0.0 from 4.11.1 I started noticing memory leaks originated on hosted services that implement a producer/consumer pattern using BufferBlock. After a closer look at a couple of process dumps, I could see lots of callback registrations on cancellation tokens presumably from DataflowBlock.OutputAvailableAsync
:
I've checked the source code of DataflowBlock.OutputAvailableAsync
and found that, since version 8.0.0, the registration to the CancellationToken provided to OutputAvailableAsync
is no longer disposed. Actually, the delegate s_handleCompletion
, which was used in earlier versions for that purpose, is never invoked. I guess that this misbehaviour, together with my implementation, that uses long-lived cancellation tokens to read from the BufferBlock, is what causes that memory leak.
Reproduction Steps
Given a hosted service implementing producer/consumer pattern using a BufferBlock
, using always the same CancellationTokenSource
to provide the CancellationToken
to OutputAvailableAsync
, then, just feed the consumer. The more items are produced, the faster the memory leak will show up.
Expected behavior
No memory leak.
Actual behavior
Memory leak
Regression?
I did not notice that behaviour in System.Threading.Tasks.Dataflow 4.11.1
Known Workarounds
In my case, switching from BufferBlock<T>
to Channel<T>
, which is not affected by this issue, was my "workaround".
Configuration
No response
Other information
No response