C# 为什么代码分析在这个方法上使用CA2000?
Visual Studio代码分析在此方法中,在C# 为什么代码分析在这个方法上使用CA2000?,c#,visual-studio,code-analysis,C#,Visual Studio,Code Analysis,Visual Studio代码分析在此方法中,在监视器变量上生成警告“在失去作用域之前处置对象”(CA2000) private void MonitorJob(IJob job, CancellationToken cancellationToken) { var monitor = new JobMonitor(job, _backend); // <- CA2000 try { var task = monitor.Run(cancellat
监视器
变量上生成警告“在失去作用域之前处置对象”(CA2000)
private void MonitorJob(IJob job, CancellationToken cancellationToken)
{
var monitor = new JobMonitor(job, _backend); // <- CA2000
try
{
var task = monitor.Run(cancellationToken);
_activeJobs[task] = monitor;
}
catch
{
monitor.Dispose();
throw;
}
}
private void MonitorJob(IJob作业,取消令牌取消令牌)
{
var monitor=new JobMonitor(作业,_后端);//我假设\u activeJobs[task]=monitor;
是一个简单的赋值,不会引发异常。如果是这样,请将存储监视器与创建监视器分开
private void MonitorJob(IJob job, CancellationToken cancellationToken)
{
Task task;
var monitor = CreateJobMonitor(job, _backend, out task);
_activeJobs[task] = monitor;
}
private JobMonitor CreateJobMonitor(IJob job, CancellationToken cancellationToken, out Task task)
{
var monitor = new JobMonitor(job, _backend);
try
{
task = monitor.Run(cancellationToken);
return monitor;
}
catch
{
monitor.Dispose();
throw;
}
通过这种方式,CreateJobMonitor意味着返回有效对象或引发异常。没有机会返回已处置的对象引用。如果在此处引发异常,您可能会泄漏此一次性对象:
private void MonitorJob(IJob job, CancellationToken cancellationToken)
{
var monitor = new JobMonitor(job, _backend);
// <- Exception
try
{
var task = monitor.Run(cancellationToken);
_activeJobs[task] = monitor;
}
catch
{
monitor.Dispose();
throw;
}
}
尽管如此,关闭警告可能还不够,此时我建议为其添加一个抑制。对于一个工具来说,运行()并不明显方法将始终引发异常。或者,它可能会在以后被释放,因为您将其存储在_activeJobs中(假设您这样做)。只需抑制警告。不使用的原因是什么?@qxg在这里如何使用它?@zerkms使用(var monitor=new JobMonitor()){var task…}
.monitor将被释放,异常将被抛出。@qxg您有没有注意到这条\u activeJobs[task]=monitor;
行?这一切都是有道理的,但给我留下了一个(次要的)后续问题:为什么同一项目中的其他代码没有遵循模式var x=new Y();try..catch
也违反了CA2000?例如,此处接受的答案在建议的CreateFirstObject()
的“安全”版本中正好具有此结构。
private void MonitorJob(IJob job, CancellationToken cancellationToken)
{
JobMonitor monitor;
try
{
monitor = new JobMonitor(job, _backend);
var task = monitor.Run(cancellationToken);
_activeJobs[task] = monitor;
monitor = null;
}
finally
{
if(monitor!=null)
{
monitor.Dispose();
}
throw;
}
}