IAsyncDisposable 参考实现错误?

IAsyncDisposable reference implementation error?

Microsoft 为 类 提供了一个参考实现,它需要同时实现 IDisposable 和 IAsyncDisposable,比如说因为它们都有这两个成员。

https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync

我在下面包含了完整的实现。 Dispose(disposing)中的这些行是我不理解的部分。

(_asyncDisposableResource as IDisposable)?.Dispose();
...
_asyncDisposableResource = null;

似乎如果我有一个 CustomDisposable 的实例并且 Dispose()DisposeAsync() 之前被调用,那么 _asyncDispoableResource 字段将具有 Dispose()调用它而不是 DisposeAsync(如果它有一个),然后无条件地设置为 null。在这种情况下,似乎 _asyncDispoableResource 永远不会被正确处理,即使稍后在 CustomDisposable 实例上调用 DisposeAsync() 也是如此。

完整参考代码:

using System;
using System.IO;
using System.Threading.Tasks;

namespace Samples
{
    public class CustomDisposable : IDisposable, IAsyncDisposable
    {
        IDisposable _disposableResource = new MemoryStream();
        IAsyncDisposable _asyncDisposableResource = new MemoryStream();

        public void Dispose()
        {
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }

        public async ValueTask DisposeAsync()
        {
            await DisposeAsyncCore();

            Dispose(disposing: false);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                _disposableResource?.Dispose();
                (_asyncDisposableResource as IDisposable)?.Dispose();
            }

            _disposableResource = null;
            _asyncDisposableResource = null;
        }

        protected virtual async ValueTask DisposeAsyncCore()
        {
            if (_asyncDisposableResource is not null)
            {
                await _asyncDisposableResource.DisposeAsync().ConfigureAwait(false);
            }

            if (_disposableResource is IAsyncDisposable disposable)
            {
                await disposable.DisposeAsync().ConfigureAwait(false);
            }
            else
            {
                _disposableResource.Dispose();
            }

            _asyncDisposableResource = null;
            _disposableResource = null;
        }
    }
}

引用您的参考资料:

It is typical when implementing the IAsyncDisposable interface that classes will also implement the IDisposable interface. A good implementation pattern of the IAsyncDisposable interface is to be prepared for either synchronous or asynchronous dispose.

这意味着通过“经典”Dispose 处理一个对象就足够了,从不调用 DisposeAsync 应该无关紧要。这就是资源设置为null的原因,所以很明显它已经被异步处理了。一次性参考的实际实施必须为此做好准备。