处理泄漏的IAsyncDisposable实例的推荐方法是什么?

Kev*_*ose 6 c# dispose asynchronous

我一直在熟悉C#8和.NET Core 3.0中(计划要添加的)某些内容,并且不确定实现IAsyncDisposable的正确方法(在撰写本文时,此链接实际上没有任何指导) )。

特别是,我不清楚在未明确处理实例的情况下该怎么办-也就是说,该实例未包装在中async using(...).DisposeAsync()也未明确调用。

我首先想到的是做与实现IDisposable时相同的事情:

  • 我的DisposeAsync()实现调用DisposeAsync(bool disposing)带有disposing: true
  • 实现终结器(带有~MyType()),该终结器调用DisposeAsync(disposing: false)
  • DisposeAsync(bool disposing)实际上释放和/或处置所有内容,并抑制if的终结disposing == true

我担心的是,没有什么可以等待DisposeAsync(bool)finalizer 的结果,而显式地等待finalizer似乎真的很危险。

当然,“只是泄漏”似乎也不理想。

为了具体起见,这里有一个(简化的)示例类,它确实有一个终结器:

internal sealed class TestAsyncReader: IAsyncDisposable
{
    private bool IsDisposed => Inner == null;
    private TextReader Inner;
    internal TestAsyncReader(TextReader inner)
    {
        Inner = inner;
    }

    // the question is, should this exist?
    ~TestAsyncReader()
    {
        DisposeAsync(disposing: false);
    }

    private ValueTask DisposeAsync(bool disposing)
    {
        // double dispose is legal, but try and do nothing anyway
        if (IsDisposed)
        {
            return default;
        }

        // should a finalizer even exist?
        if (disposing)
        {
            GC.SuppressFinalize(this);
        }

        // in real code some resources explicitly implement IAsyncDisposable,
        //   but for illustration purposes this code has an interface test
        if (Inner is IAsyncDisposable supportsAsync)
        {
            var ret = supportsAsync.DisposeAsync();
            Inner = null;
            return ret;
        }

        // dispose synchronously, which is uninteresting
        Inner.Dispose();
        Inner = null;
        return default;
    }

    public ValueTask DisposeAsync()
    => DisposeAsync(disposing: true);
}
Run Code Online (Sandbox Code Playgroud)

那么,关于正确处理泄漏IAsyncDisposable实例是否有任何指导?

Dmy*_*lov 5

基础上它是如何.NET核心类(如内部实现的例子这里距离),并提出了一些建议还有,我想说的是,当你需要实现IAsyncDisposable,良好的做法是实现这两个IAsyncDisposableIDisposable。在这种情况下,IAsyncDisposable仅在需要异步处理的情况下才负责显式场景,而IDisposable根据可抛弃模式实践应按惯例照常执行,它将为所有后备场景提供服务,包括最终确定时的场景。因此,您不需要像DisposeAsync(bool disposing)-终结处理程序中不能也不应该进行异步处理。唯一的坏消息是您必须同时支持资源回收的两个路径(同步和异步)。