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

Mil*_*use 7 .net c# asynchronous

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

using (var transaction = new Transaction())
{
    // do some stuff
}
Run Code Online (Sandbox Code Playgroud)

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

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

public async void Dispose(){ // roll back everything on error }
Run Code Online (Sandbox Code Playgroud)

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

mka*_*kaj 5

调用 Task.Run(...) 怎么样?它将指定的工作排队以在线程池上运行。

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

  • 如果你这样做,请小心死锁。例如,如果您从 UI 线程调用 dispose,并且您的 RollBackAsync 在 UI 线程繁荣死锁上有其他等待。调用“var result = RollbacAsync().Result;”可能更安全 (4认同)

Gus*_*dor 2

您只能await在方法返回时使用Task,Task<T>或者等待的其他实现。

IDisposable没有定义Task Dispose()方法。您始终可以编写自己的代码,但退出块时不会调用它using。

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