微软为实现同时需要实现IDisposable和IAsyncDisposable接口的类提供了一个参考实现,例如因为它们有这两个接口的成员。
https://learn.microsoft.com/zh-cn/dotnet/standard/garbage-collection/implementing-disposeasync
下面是完整的实现代码。我不理解Dispose(disposing)
中的这些行是什么意思。
(_asyncDisposableResource as IDisposable)?.Dispose();
...
_asyncDisposableResource = null;
似乎如果我有一个CustomDisposable实例,并且在DisposeAsync()之前调用了Dispose(),那么_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;
}
}
}
this.Dispose(true)
。在本例中,它被省略了。因此,您可以抑制终结器以确保不尝试处理已处置的资源。 - Emanuel Vintilă