I'm writing a utility class for some asynchronous code, and I want to ensure that I don't create memory leaks with the design. Suppose I've got code which executes similarly to the class below. (Obviously you wouldn't write code that works like this, but I've got several code paths which all converge into a single underlying function, and one of those code paths is effectively doing this). The key point in the code is that nothing in my code holds a reference to either the TaskCompletionSource
or its Task
, though .NET might be doing some voodoo which does root them.
Suppose that Foo instances are created as needed and are not permanently rooted. Is tcs.Task
rooted? More importantly, suppose request
never completes, so the result doesn't get set. Would tcs.Task
hang around forever? What about the continuation task? Or, is their lifetime dependent on the Foo object and they will go away when the Foo instance gets GC-ed?
class Foo
{
public void Bar(Action<Action<object>> request, Action<T> callback)
{
var tcs = new TaskCompletionSource<object>();
request(result => tcs.SetResult(result)); // this runs asynchronously
tcs.Task.ContinueWith(task => callback(task.Result));
}
}