![](/img/trans.png)
[英]CA2000 : Microsoft.Reliability call System.IDisposable.Dispose on object before all references to it are out of scope
[英]CA2000 : Microsoft.Reliability : Call System.IDisposable.Dispose on object 'dt' before all references to it are out of scope
当我运行代码分析工具时,我得到以下内容:
警告1 CA2000:Microsoft.Reliability:在方法“Class1.test.testMethod()”中,对象“dt”未沿所有异常路径放置。 对所有对它的引用超出范围之前,在对象'dt'上调用System.IDisposable.Dispose。 如何解决警告?
public void testMethod()
{
DataTable dt = new DataTable();
DataTable dt1= new DataTable();
try
{
if (dt.Rows.Count == 0)
{
dt1.Merge(dt);
}
}
catch
{
throw;
}
finally
{
if (dt != null) dt.Dispose();
if (dt1 != null) dt1.Dispose();
}
}
不确定为什么会出现该错误,但您可以尝试在方法中using
语句块并查看错误是否消失。 试试吧:
public void testMethod()
{
using (DataTable dt = new DataTable())
using (DataView dv = new DataView(dt))
{
//your work
}
}
如果在对所有对象的所有引用都超出范围之前没有明确地处置一次性对象,则当垃圾收集器运行对象的终结器时,该对象将在某个不确定的时间处置。 由于可能会发生异常事件以阻止对象的终结器运行,因此应该明确地处理该对象。
要修复违反此规则的行为,请在对对象的所有引用超出范围之前调用对象上的
System.IDisposable.Dispose
。请注意,您可以使用using语句(在Visual Basic中使用)来包装实现
IDisposable
对象。 以这种方式包裹的物体将自动放置在使用块的附近。
using (DataTable dt = new DataTable())
using (DataView dv = new DataView(dt))
{
}
在代码的第7行中,您创建了一个未使用的虚拟DataTable。 编译器抱怨DataTable和DataView对象。 更改下面的代码,它将工作。
public class Class1
{
public class test
{
public void testMethod()
{
DataTable dt = null;
DataView dv = null;
try
{
// dt must be assigned a value only within the try block
dt = new DataTable(dt);
dv = new DataView(dt);
}
catch
{ }
finally
{
if (dt != null) dt.Dispose();
if (dv != null) dv.Dispose();
}
}
}
}
更新
如果你同时处理dt
和dv
你将得到CA2202错误 。 这是因为dt
被处理了两次。 一旦配置dt
和配置dv
一次。 为避免这种情况,必须在try / catch块的末尾为dt
赋值null
。
try
{
dt = new DataTable(dt);
dv = new DataView(dt);
dt=null;
}
我怀疑错误正在发生,因为您正在创建两个DataView
,并且只会丢弃其中一个:您将dv
初始化为新的DataView
,然后在try
块中分配另一个。 当你点击finally
,初始赋值中的那个不会被处理,因为你没有引用它。
修改你的声明DataView dv = new DataView ()
只是声明变量,而不是初始化它:
public void testMethod()
{
DataTable dt = new DataTable();
DataView dv = null;
try
{
dv = new DataView(dt);
}
finally
{
if (dt != null) dt.Dispose();
if (dv != null) dv.Dispose();
}
}
注意 :这直接修复了您的第二条错误消息(关于dv
),并间接解决了第一条(关于dt
)。 引发第一个错误是因为,如果dv
的冗余初始化是抛出异常,则不会丢弃dt
- 因此删除该初始化会修复错误。
可能是因为DataTable初始化器理论上可能会在处置之前中断。 您可以尝试使用null初始化它,并在try块中使用新的DataTable实例进行初始化。 毕竟你终于可以进行可空的测试了。
就像是
public class Class1
{
public class test
{
public void testMethod()
{
DataTable dt = null;
try
{
dt = new DataTable();
}
catch
{ }
finally
{
if (dt != null) dt.Dispose();
}
}
}
}
发生的原因是您在try块之外初始化dt。
public void testMethod()
{
DataTable dt = null;
DataView dv = null;
try
{
dt = new DataTable();
dv = new DataView(dt);
}
catch
{
}
finally
{
if (dt != null) dt.Dispose();
if (dv != null) dv.Dispose();
}
}
}
如其他答案中所述,您也可以使用块而不是尝试...最后。
public void testMethod()
{
using (DataTable dt = new DataTable())
{
using (DataTable dv = new DataView(dt))
{
}
}
}
一个问题:你打算让test
类成为Class1
的嵌套类吗?
public class test
{
public void testMethod()
{
DataTable dt = null;
DataView dv = null;
try
{
dv = new DataView(dt);
}
catch
{ }
finally
{
if (dt != null) dt.Dispose();
if (dv != null) dv.Dispose();
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.