When using System.Threading.Tasks.Dataflow
, if I link block a
to block b
, will the link keep b
alive? Or do I need to keep a reference to b
around to prevent it from being collected?
internal class SomeDataflowUser
{
public SomeDataflowUser()
{
_a = new SomeBlock();
var b = new SomeOtherBlock();
_a.LinkTo(b);
}
public void ReactToIncomingMessage( Something data )
{
// might b be collected here?
_a.Post( data );
}
private ISourceBlock<Something> _a;
}
In addition to @Eric great explanation of GC behavior I want to address the special case related to TPL-Dataflow. You can easily see the behavior that LinkTo
yields from a simple test. Notice that nothing, to my knowledge, is holding on to b
except for its link to a
.
[TestFixture]
public class BlockTester
{
private int count;
[Test]
public async Task Test()
{
var inputBlock = BuildPipeline();
var max = 1000;
foreach (var input in Enumerable.Range(1, max))
{
inputBlock.Post(input);
}
inputBlock.Complete();
//No reference to block b
//so we can't await b completion
//instead we'll just wait a second since
//the block should finish nearly immediately
await Task.Delay(TimeSpan.FromSeconds(1));
Assert.AreEqual(max, count);
}
public ITargetBlock<int> BuildPipeline()
{
var a = new TransformBlock<int, int>(x => x);
var b = new ActionBlock<int>(x => count = x);
a.LinkTo(b, new DataflowLinkOptions() {PropagateCompletion = true});
return a;
}
}