Michael Hagar Michael Hagar - 2 months ago 16
C# Question

How to dispose of an object that it created in a task?

I have a foreach loop that creates multiple tasks like this:

[edit: CreateDisposableAsync returns a Task[IDisposable]]

foreach(...)
{
tasks.Add(CreateDisposableAsync());
}


and later I await on all of these tasks, and catch any exceptions:

try
{
await Task.WhenAll(tasks);
}
catch (AggregateException)
{
// handle exceptions
}


but the call to CreateDisposableAsync() returns an IDisposable, which I want to be disposed whether or not there was an exception in any of the tasks. How can I do this?

[Edit: It turns out that the CreateDisposableAsync() function was disposing of its created object if itself threw an exception, so there was nothing wrong with the original code.]

Answer

From the comments

Q: with the exception of disposing the result do you do (or want to do) anything else with the result in the calling code

A: No I do not

The easiest way to do this is to have the CreateDisposableAsync method clean up its own resources before it returns and return Task instead of Task<IDisposable>. The existing calling code shown in the OP would not have to change.

// change the signature
async Task CreateDisposableAsync(){
   // use using blocks for anything that needs to be disposed
   // try/finally is also acceptable
   using(var someDisposableInstance = new SomethingDisposable()){
      // implementation
   }
}
Comments