在 using 语句中调用异步方法

7
我想使用异步调用发送一条消息,但在此过程中会使用一些可丢弃的资源。我不确定如何正确处理这种情况。
using(IDisposable disposeMe = new DisposableThing())
{
    MethodAsync(disposeMe);
}

有什么方法可以做到这一点。异步方法没有任何回调。

编辑:

根据@Servy的建议,接受的答案的实现已更改为:

public async Task Method()
{
    using(IDisposable disposeMe = new DisposableThing())
    {
        await MethodAsync(disposeMe);
    }
}

1
异步操作应该负责处理对象的释放。 - Petr Újezdský
1个回答

10

异步方法没有任何回调函数

那真是个问题,而且是一个非常大的问题。如果可能的话,应该解决这个问题;除非有非常充分的原因不这样做,在所有异步方法中都应该提供某种方式让调用者知道它们何时完成,无论是回调、返回任务(Task)、触发事件等。对于依赖可释放资源的异步方法,这尤其令人担忧。

如果您确实没有办法在操作完成时得到通知,那么您就无法在方法完成后调用Dispose。您唯一能够确保在异步操作仍需要它时不释放资源的方法是泄漏资源并根本不释放它。如果可释放资源具有终结器,那么它可能最终会被清理掉,但并不是所有可释放资源都会这样做。

如果您可以修改异步方法,则只需在回调、任务的延续或相关事件的处理程序中调用Dispose。除非您可以使用await异步操作(因为await非常好用),否则您将无法使用using


这并不完全正确。异步方法确实返回一个任务(Task)。抱歉让您感到困惑,我的意思是它的签名中没有传递回调函数。 - Brian Triplett
@BrianTriplett 如果它返回一个任务,则可以简单地调用ContinueWith来添加回调,或者更好的办法是使用await - Servy
你能举个例子吗?await应该放在哪里?在using块内部吗?这是否需要将包含using块的方法标记为async? - Brian Triplett
@BrianTriplett 如果你想使用await,你需要等待异步方法完成。这确实要求调用该方法的方法也是async的。如果你不想或者不能这样做,那么你可以在任务上调用ContinueWith方法,并在该继续中调用Dispose,同时移除using语句以避免过早释放资源。 - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接