Visual Studio代码分析在此方法的monitor
变量上生成警告“在丢失范围之前处置对象”(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;
}
}
我理解CA2000的功能,我通常能够弄清楚为什么我的代码违反规则并进行适当的更改。
然而,在这种情况下,我感到难过 - 这真的是假阳性,还是我错过了什么?
使用Visual Studio 2015 Enterprise Edition,以.NET 4.5为目标,使用C#6。
答案 0 :(得分:2)
如果抛出异常,你可以泄漏这个一次性物品:
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;
}
}
这可能是由ThreadAbortException
或运行时注入线程的任何其他异常引起的。我建议在try
块之外声明变量,但在其中分配。另外,在成功将其分配给null
时将其设置为_activeJobs
。
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;
}
}
即便如此,关闭警告可能还不够,此时我建议添加抑制警告。
答案 1 :(得分:0)
我假设_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意味着返回有效对象或抛出异常。没有机会返回已处置的对象引用。