开发者

Failsafe disposal in an async world

开发者 https://www.devze.com 2023-02-11 00:21 出处:网络
In the synchronous world, C# makes the management of all things disposable really rather easy: using(IDisposable someDisposable=bla.bla())

In the synchronous world, C# makes the management of all things disposable really rather easy:

using(IDisposable someDisposable=bla.bla())
{
     //do our bidding
}
//don't worry too much about it

However, when we go async, we no longer have the convenience of the using block. One of the best strategies I've encountered is the CCR iterator which allows us to use async code "as if it were synchronous". This means we can keep our using block in the iterator handler and not get too bogged down in the complex decision of when to dispose and catching all the cases where disposal is required.

However, in开发者_如何学Python many cases, invoking CCR can seem like overkill, and to be honest, although I'm quite comfortable with CCR, to the uninitiated it can look like double-dutch.

So my question is: what other strategies exist for the management of one's IDisposable's, when the disposable objects must persist beyond the immediate scope?


One approach is to have all methods that would not be able to coexist with the disposal method take a lock while they run, and check a queue for objects needing disposal when they finish. The disposal method could then add itself to the queue, use TryEnter to try to acquire the lock, dispose the object and delete it from the queue if successful, or else let the current holder of the lock handle the disposal.


It turns out that this problem was also on the minds of the language designers.

The correct answer to this question is now to use the Task based versions of the asynchronous APIs that have been provided for almost all asynchronous operations, coupled with the new C# async/await keywords. These allow us to keep everything in scope over the lifetime of asynchronous operations:

async Task<int> DoSomething()
{
    using(var foo = new SomeDisposableThing())
    {
         await foo.DoSomethingAsync();
    }
    return 0;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号