在IDisposable.Dispose()中使用异步调用

时间:2016-10-27 13:30:12

标签: c# .net asynchronous

我需要实现一个简单的事务。在这种情况下,我的事务类实现了IDisposable接口。这样我就可以在using语句中使用我的事务类,如果在该范围内发生任何错误,那么在处理事务时所有事情都会被回滚。

using (var transaction = new Transaction())
{
    // do some stuff
}

“做一些事情”还包括一些客户端/服务器连接等。

现在,如果“做一些事情”引发任何错误,我会回滚所有内容。

public async void Dispose(){ // roll back everything on error }

这可能包括清理我需要调用异步操作的服务器上的一些资源。这引出了我的问题:我可以安全地使用aspose关键字来实现我的Dispose()实现中的await关键字吗?或者由于同步上下文问题或类似的原因,这可能导致竞争条件?

3 个答案:

答案 0 :(得分:4)

如何调用Task.Run(...)。它将指定的工作排队,以便在ThreadPool上运行。

    public void Dispose()
    {
        if (_thereWasAnError)
        {
            Task.Run(async () => await RollbackAsync()).Wait();
        }
    }

答案 1 :(得分:1)

当方法返回awaitTask或其他等待实现时,您只能使用Task<T>

IDisposable未定义Task Dispose()方法。您可以随时编写自己的,但在退出using块时不会调用它。

根据资源中的锁定机制,您可能会面临async void的竞争条件(避免使用!)。

答案 2 :(得分:0)

就像Gusdor已经提到过in his answer一样,您不能简单地将async关键字添加到Dispose()界面的IDisposable方法中。 但是,从C#8.0开始,可以使用新的异步处理接口:IAsyncDisposable

以此,您可以实现真正的异步处理。 要了解其工作原理,请阅读Microsoft的这篇出色文章:https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync