7

I want to send a message using an asynchronous call but disposable resources are used in the process. I'm not sure how to properly handle this.

using(IDisposable disposeMe = new DisposableThing())
{
    MethodAsync(disposeMe);
}

Any ideas how to do this. The async method does not have any callback.

EDIT:

Based on the suggestion the accepted answer by @Servy. The implementation was changed to:

public async Task Method()
{
    using(IDisposable disposeMe = new DisposableThing())
    {
        await MethodAsync(disposeMe);
    }
}
1
  • 1
    The async operation should take over the responsibility of disposing the object. Commented Dec 6, 2013 at 19:03

1 Answer 1

10

The async method does not have any callback

Well that's a problem. A very big problem. If at all possible you should fix that; unless there is a very good reason not to, all asynchronous methods should provide some means for the caller to know when they have completed, whether it's a callback, returning a Task, firing an event, etc. It's particularly troubling for an asynchronous method that is dependent on a disposable resource to do this.

If you really do have no way of being notified when the operation completes, then there is no way for you to call Dispose after the method completes. The only means you have of ensuring you don't dispose of the resource while the async operation still needs it is to leak the resource and not dispose of it at all. If the disposable resource has a finalizer it's possible it will be cleaned up eventually, but not all disposable resources do so.

If you can modify the asynchronous method somehow then you simply need to call Dispose in the callback, or in a continuation of the task, or in a handler of the relevant event. You won't be able to use a using unless you can await the asynchronous operation (because await is just awesome like that).

Sign up to request clarification or add additional context in comments.

4 Comments

That's not entirely true. The async method does return a Task. Sorry for the confusion. I meant that it does not have a callback passed in as part of its signature.
@BrianTriplett If it returns a task then you can simply call ContinueWith as a means of adding a callback, or better yet, await it.
Can you give an example? Where would the await be? Within the using block? Would that require the method containing the using block to now be marked async?
@BrianTriplett You would await the async method, if you waneted to use await. It would indeed require that the calling method be async, yes. If you don't want to do that, or can't, then you would simply call ContinueWith on the task and call Dispose in that continuation, while also removing the using so as to not dispose of it early.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.