为什么IDisposable会立即调用Dispose()?

时间:2013-09-20 10:49:25

标签: c# asp.net-mvc-4 iis idisposable

我有一个在应用程序中的另一个项目中使用IDisposable的Web应用程序(asp.net mvc 4)。这一切都可以从visual studio(2012)进行编译和运行,但是当使用浏览器运行Web应用程序时(使用IIS 8 Express)会抛出异常。

我使用IDisposable的密封类在using语句中,并且在使用大括号中的任何代码之前调用Dispose()方法,即

using (MySealedClass msc = new MySealedClass())
{
  //Code doesn't reach here. Dispose() is called beforehand
  //My code here . . . 
}

构造函数及其依赖是:

private readonly IList<IntPtr> _intPtrList;

public MySealedClass()
{
    _intPtrList = new List<IntPtr>(); 
}

所以我认为那里不应该有任何问题。为了测试这个,我在代码中更早地实例化了MySealedClass,而没有使用using语句,如下所示:

MySealedClass msc = new MySealedClass()

代码可以超越这一点,然后我可以调用它上面的方法。

我在MSDN上看到过一些示例,其中using语句代码由编译器转换为try catch模式,但我不认为这解释了错误,因为错误发生在我的主块代码之前。

任何人都可以解释使用声明是否正在做额外的事情?例如它扫描代码块的其余部分,如果有不喜欢的东西,则调用Dispose()方法。

我的怀疑在于IIS,之前,我有不安全的代码错误(尽管web.config中的配置正确)但我忘了让IIS以x64运行应用程序。使用regedit做完之后很好。

附加信息:在使用块中,存在不安全的代码并使用[DllImport]属性调用外部dll。

非常感谢

2 个答案:

答案 0 :(得分:2)

using (MySealedClass msc = new MySealedClass())
{
  //Code doesn't reach here. Dispose() is called beforehand
  //My code here . . . 
}

由编译器翻译成与此类似的东西:

MySealedClass msc = null;
try
{
  msc = new MySealedClass();
  //My code here . . . 
}finally{
  if(msc != null){
    ((IDisposable)msc).Dispose():
  }
}

编译器不会事先检查您的代码,如果发现它不喜欢的话,就会跳过它。

所以对我来说,似乎在你到达之前你正在检查你得到一个异常,导致它转到finally块并处理你的对象。

答案 1 :(得分:0)

根据MSDN文档,“using语句确保即使在对象上调用方法时发生异常也会调用Dispose。”

为什么不调试使用块中提​​到的不安全代码。可能是外部dll内引发的异常导致调用Displose()方法?