首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何处理Dispose抛出的异常?

如何处理Dispose抛出的异常?
EN

Stack Overflow用户
提问于 2009-06-23 11:04:17
回答 3查看 23.1K关注 0票数 23

最近,我在研究一些关于object not disposed的棘手bug。

我在代码中发现了一些模式。据报道,一些m_foo没有被释放,而SomeClass的所有实例似乎都已经被释放了。

代码语言:javascript
复制
public class SomeClass: IDisposable
{
    void Dispose()
    {
       if (m_foo != null)
       {
          m_foo.Dispose();
       }
       if (m_bar != null)
       {
          m_bar.Dispose();
       }   
    }

    private Foo m_foo;

    private Bar m_bar;

}

我怀疑Foo.Dispose可能会抛出异常,因此不会执行以下代码,因此不会释放m_bar。

因为Foo/Bar可能来自第三方,所以不能保证不抛出异常。

如果只使用try-catch包装所有Dispose调用,代码将变得笨拙。

处理此问题的最佳实践是什么?

EN

回答 3

Stack Overflow用户

发布于 2009-06-23 03:18:30

如果在finalization上下文中调用Dispose()并抛出异常,您的进程将被终止。

如果您怀疑Foo.Dispose()抛出了一个异常,我会尽可能最后处理它,并将它包装在try/catch中。尽你所能在catch中摆脱它--将reference设置为null。从Dispose()抛出异常是非常糟糕的,应该避免。

不幸的是,如果这是有bet的第三方代码,你最好的办法就是让他们来修复它。你不应该在它之后手动清理它。

希望这能有所帮助。

票数 7
EN

Stack Overflow用户

发布于 2009-10-24 14:46:22

因为你不必在using()语句中分配变量--为什么不使用'stacked‘using语句呢?

代码语言:javascript
复制
void Dispose()
{
    // the example in the question didn't use the full protected Dispose(bool) pattern
    // but most code should have if (!disposed) { if (disposing) { ...

    using (m_foo)
    using (m_bar)  
    {
        // no work, using statements will check null 
        // and call Dispose() on each object
    }

    m_bar = null;
    m_foo = null;
}

“堆叠”using语句的扩展如下:

代码语言:javascript
复制
using (m_foo)
{
    using (m_bar) { /* do nothing but call Dispose */ }
}

因此Dispose()调用被放在单独的finally块中:

代码语言:javascript
复制
try {
    try { // do nothing but call Dispose
    }
    finally { 
        if (m_bar != null)
            m_bar.Dispose(); 
    }
finally { 
    if (m_foo != null)
        m_foo.Dispose();
}

我很难在一个地方找到这方面的参考资料。“堆叠的”using语句可以在old Joe Duffy blog post中找到(参见“C#和VB Using语句,C++堆栈语义”一节)。IDisposable上的许多StackOverflow answers都引用了Joe Duffy的帖子。我还发现了一个recent question,其中使用局部变量语句进行堆叠似乎很常见。除了C# language spec之外,我找不到finally块的链接( C# 3.0规范中的8.13节),并且只能在一个'using‘块中找到多个变量,这并不是我所建议的,但是如果你破坏IL,你会发现try/finally块是嵌套的。在null检查中,同样来自C#规范:“如果获取了null资源,则不会调用Dispose,也不会抛出任何异常。”

票数 2
EN

Stack Overflow用户

发布于 2016-08-21 02:45:18

在我的例子中,这是因为一个线程在关闭窗体时访问UI元素。我通过中止form close上的线程重新解决了这个问题。("FormClosing“事件)

代码语言:javascript
复制
FormClosing += (o, e) => worker.Abort();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1030455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档