使用抽象 class 的一次性模式实现有什么问题
what's the problem in idisposable pattern implementation withing abstract class
我有一个抽象 class 的以下实现,但从 sonarqube 代码分析中收到警告
public abstract class BackgroundService : IHostedService, IDisposable
{
private bool _disposedValue;//https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
public virtual Task StartAsync(CancellationToken cancellationToken)
{
_executingTask = ExecuteAsync(_stoppingCts.Token);
if (_executingTask.IsCompleted)
{
return _executingTask;
}
return Task.CompletedTask;
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
{
return;
}
try
{
_stoppingCts.Cancel();
}
finally
{
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)//todo kamran
{
if (_disposedValue)
{
return;
}
if (disposing)
{
_stoppingCts.Cancel();
}
_disposedValue = true;
}
~BackgroundService()
{
Dispose(false);
}
}
声纳立方体错误是
Fix this implementation of 'IDisposable' to conform to the dispose pattern.
Code Smell
Provide 'protected' overridable implementation of 'Dispose(bool)' on 'BackgroundService' or mark the type as 'sealed'.
'BackgroundService.Dispose()' should not be 'virtual' or 'abstract'.
'BackgroundService.Dispose()' should also call 'Dispose(true)'.
你的 Dispose()
方法不应该是虚拟的:你的 Dispose(bool)
方法应该是(并且它是被继承者覆盖的那个):这是一种常见且已知的模式,你可以在其中使用 bool
参数以了解您是确定性地处理(通过调用 Dispose
或 using
块)还是通过终结器(您尚未在摘要 class 中实现),顺便说一句),你只需要处理非托管引用。
您缺少用于使模式完整的终结器:
~BackgroundService() {
Dispose(false);
}
否则,GC.SuppressFinalize(this)
没有意义
我有一个抽象 class 的以下实现,但从 sonarqube 代码分析中收到警告
public abstract class BackgroundService : IHostedService, IDisposable
{
private bool _disposedValue;//https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose
private Task _executingTask;
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
public virtual Task StartAsync(CancellationToken cancellationToken)
{
_executingTask = ExecuteAsync(_stoppingCts.Token);
if (_executingTask.IsCompleted)
{
return _executingTask;
}
return Task.CompletedTask;
}
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (_executingTask == null)
{
return;
}
try
{
_stoppingCts.Cancel();
}
finally
{
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)//todo kamran
{
if (_disposedValue)
{
return;
}
if (disposing)
{
_stoppingCts.Cancel();
}
_disposedValue = true;
}
~BackgroundService()
{
Dispose(false);
}
}
声纳立方体错误是
Fix this implementation of 'IDisposable' to conform to the dispose pattern.
Code Smell
Provide 'protected' overridable implementation of 'Dispose(bool)' on 'BackgroundService' or mark the type as 'sealed'.
'BackgroundService.Dispose()' should not be 'virtual' or 'abstract'.
'BackgroundService.Dispose()' should also call 'Dispose(true)'.
你的 Dispose()
方法不应该是虚拟的:你的 Dispose(bool)
方法应该是(并且它是被继承者覆盖的那个):这是一种常见且已知的模式,你可以在其中使用 bool
参数以了解您是确定性地处理(通过调用 Dispose
或 using
块)还是通过终结器(您尚未在摘要 class 中实现),顺便说一句),你只需要处理非托管引用。
您缺少用于使模式完整的终结器:
~BackgroundService() {
Dispose(false);
}
否则,GC.SuppressFinalize(this)
没有意义