搜索未被处理的IDisposable对象的完整解决方案工具

8
作为我们大多数人都知道的,为了在 .net 中有效地管理内存,最好始终在实现 IDisposable 接口的对象上调用 Dispose()。然而,在日常编写大量代码时,很容易忘记执行此操作。
有没有人知道一种工具,可以搜索 c# 解决方案并找到所有没有被处理的可处理对象的位置?我可以看到在像位图这样的对象被分配给属性的情况下,这种方法可能不起作用,但即使是更基本的检查器也会有价值。
感谢您的时间。

如果你养成检查对象是否可处理的习惯,你就会发现很难忘记。我几乎总是尝试将某些东西包装在using块中,如果编译器抱怨该对象没有实现IDisposable,则将其删除。这样犯错误比较好。此外,当您将可处理对象用作对象级实例变量时,养成一个好习惯,即在将对象添加到代码中时立即编写处理/清理代码。话虽如此,工具将是一个不错的安全保障。 - Jason Down
当我点赞这个问题时,我看到了三只跳舞的独角兽。太棒了! - Jason Down
当然没问题,Jason。但是,你会发现自己在使用一些以前没有接触过的新类,比如GraphicsPath或其他任何东西,然后你就继续赶下一个deadline了。这并不是要削弱勤勉尽责的重要性,正如你所说,这是发布代码之前的安全保障。 - Steve Sheldon
4个回答

14

我发现Visual Studio 2010可以完全满足我想要的功能。要实现这种行为,请执行以下操作:

  • 按照如何创建自定义规则集中所述的方式创建一个新的代码分析规则集
  • 将以下规则添加到您的规则集中:

    • 在超出范围之前处理对象
    • 不要多次释放同一对象
    • 应该处理可释放字段
    • 释放方法应该调用基类释放

或者将它们作为常规代码分析规则的一部分运行。虽然不是万无一失,但比没有安全措施要好。


这非常有效,并且有额外的好处,可以在编译时而不是运行时捕获问题。 +1 - Robert Levy
这确实很不错。由于我没有MSVS 2010 Ultimate(并且根本不知道Code Analysis功能),所以我编写了自己的解决方案:EyeDisposable。我不知道MSVS 2010有多可靠,但我使用了运行时检查方法,所以也许你想试试:p - kizzx2
那个选项窗口已经过时了。注意:此属性页已被弃用,并将在未来的产品发布中删除。你能说出任何替代方案吗?谢谢。 - T.Todua

1

假设您正在使用建议的模式,在手动调用Dispose时抑制终结,您可以通过添加一些代码来告诉您每当在终结器线程上调用Dispose时发生的错误。

~MyClass()
{  
     Dispose( false );
     Console.WriteLine( "Argh, release me! I want better co-workers!" );
}

public Dispose()
{  
     Dispose( true );
     GC.SuppressFinalization( this );
}

public Dispose( bool invokedByDeveloper )
{  
     if( invokedByDeveloper )
         // free managed resources

     // free unmanaged resources
}

可以像BrandonZeider建议的那样使用内存分析器。ANTS是一个非常好的,尽管有点贵的分析器。Jetbrains也制作了一个很好的分析器,你可以在不购买的情况下尝试30天。


你可以考虑在框架类周围创建包装器类,并将底层资源仅作为属性公开。这使得即使您没有编写这些类或它们被封闭,也可以使用相同的技术。 - Morten Mertner
1
恐怕现在已经太晚了。如果能找到合适的工具就太好了,否则我可能会自己写一个。 - Steve Sheldon
1
我应该补充一点,使用内存分析器确实非常简单,并且非常值得投资,因此在花费过多时间进行任何手动解决方案之前,请考虑使用它。 - Morten Mertner
1
这些工具为什么不存在,或者说它们被称为内存分析器而不是“这是你的错误”工具,这其中有原因。除了简单情况(可以由VS代码分析或FxCop找到)之外,你无法仅通过查看源代码来确定正确的行为,因此对于任何中等复杂的情况都需要使用分析器。 - Morten Mertner
1
我就喜欢当有人点踩却不留言解释为什么。 - Morten Mertner
显示剩余5条评论

1
我最喜欢的内存分析工具是Redgate的Ants Profiler。它非常简单易用,并且有很多教程可以帮助你入门。最好的是它提供14天的免费试用,这样你可以在购买之前先试用一下,确保它适合你的需求。

谢谢你的回答,Brandon,但那不是我正在寻找的。我正在寻找一个代码分析器,它可以搜索整个项目,生成报告,并指出“在文件x的第y行,对象foo从未被处理”。 - Steve Sheldon
听起来很酷,我还没有听说过可以做到这一点的静态代码分析工具...可能不太准确,因为你无法预测运行时条件,但这个概念很酷。 - BrandonZeider

1

防止这种问题的最佳方法可能是变得“着迷”于处理它。考虑通过计划何时以及在代码中的哪个位置处理您的对象并将其处理来提高效率。如果您在团队中工作,请向他们提出处理建议。

如果您的可处理对象的范围很短暂,可能仅包含在某个方法的一小部分中,请使用using将其包装起来,以确保其被处理。我会尽可能使用using(语法是否正确?)。

显然,这些不是自动化建议,不总是有效的,但是保持正确的心态并学习可以应用于日常工作的最佳实践并不难。这是我的两分钱。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接