是否有可能并行调用 DisposeAsync 方法?
Is it possible, that DisposeAsync method is called in parallel?
从the official documentation中获取以下代码:
using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
public class ExampleAsyncDisposable : IAsyncDisposable, IDisposable
{
private Utf8JsonWriter _jsonWriter = new Utf8JsonWriter(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)
{
_jsonWriter?.Dispose();
}
_jsonWriter = null;
}
protected virtual async ValueTask DisposeAsyncCore()
{
if (_jsonWriter is not null)
{
await _jsonWriter.DisposeAsync();
}
_jsonWriter = null;
}
}
问题是:下面的场景是否可能?为什么?
- 调用了
DisposeAsync
方法。
- 在
_jsonWriter
设置为 null
之前,再次调用 DisposeAsync
。
是的,可以并发 DisposeAsync
调用。也可以同时进行 Dispose
调用。从技术上讲,实施 应该 正确处理此问题,但在实际代码中,并发 Dispose
或 DisposeAsync
调用非常罕见,因此大多数实施都这样做不 正确处理。
如果这是一个令人担忧的问题,我建议使用我的 Disposables 库,它可以确保处理时的精确一次语义。但是,它是根据类型要实现 IAsyncDisposable
或 IDisposable
而不是两者都实现的假设编写的。
从the official documentation中获取以下代码:
using System;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
public class ExampleAsyncDisposable : IAsyncDisposable, IDisposable
{
private Utf8JsonWriter _jsonWriter = new Utf8JsonWriter(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)
{
_jsonWriter?.Dispose();
}
_jsonWriter = null;
}
protected virtual async ValueTask DisposeAsyncCore()
{
if (_jsonWriter is not null)
{
await _jsonWriter.DisposeAsync();
}
_jsonWriter = null;
}
}
问题是:下面的场景是否可能?为什么?
- 调用了
DisposeAsync
方法。 - 在
_jsonWriter
设置为null
之前,再次调用DisposeAsync
。
是的,可以并发 DisposeAsync
调用。也可以同时进行 Dispose
调用。从技术上讲,实施 应该 正确处理此问题,但在实际代码中,并发 Dispose
或 DisposeAsync
调用非常罕见,因此大多数实施都这样做不 正确处理。
如果这是一个令人担忧的问题,我建议使用我的 Disposables 库,它可以确保处理时的精确一次语义。但是,它是根据类型要实现 IAsyncDisposable
或 IDisposable
而不是两者都实现的假设编写的。