WPF 代码分析:CA1001 拥有一次性字段的类型应该是一次性的

WPF code analyze : CA1001 Types that own disposable fields should be disposable

在我的 WPF 应用程序代码中,我收到以下警告:

CA1001 Types that own disposable fields should be disposable Implement IDisposable on 'MainWindow' because it creates members of the following IDisposable types: 'BackgroundWorker', 'DataTable'. If 'MainWindow' has previously shipped, adding new members that implement IDisposable to this type is considered a breaking change to existing consumers. yesMonitor MainWindow.xaml.cs 38

主要代码 window:

public partial class MainWindow : Window
{
    // Some code..    
}

出现这些警告的原因是什么?

This is not a as simple a question as it looks, due to MainWindow being a class that has special meaning in a WPF application.

我觉得你在这里把自己弄糊涂了。 MainWindow 只是另一个 class。碰巧它在应用程序启动时被打开。然而,这是默认行为,它可以更改

查看 App.xaml 文件,您会看到 StartupUri 属性 设置为 MainWindow,您可以根据需要更改它。

MainWindow没有什么特别之处,它不是WPF需要的某种超级重要的内置圣弥赛亚,哎呀,如果你想删除它甚至可以删除它。由于它只是另一个 class,它 应该遵循 与任何其他 class 相同的原则。在您的情况下,您正在创建实现 IDisposable 的 classes 的实例,因此,在您的 class 中实现 IDisposable 也是处置您的实例的好习惯。否则,垃圾收集器 可能 忽略它们,您可能会发现内存泄漏。请参阅以下消息:

Types that own disposable fields should be disposable Implement IDisposable on 'MainWindow' because it creates members of the following IDisposable types...

我不是 IDisposable 原则和体系结构方面的专家,但您应该在需要的地方实施它。

请参阅 documentation 有关如何正确实施 IDisposable 的指南。

您需要在 MainWindow 上实现 IDisposable。实际上,您在 MainWindow class 中有一些资源需要关闭。当 MainWindow 将被销毁时,它们不会关闭。为此,我们实现了 IDisposable,并在实现中处理了这些对象。

https://msdn.microsoft.com/library/ms182172.aspx

在你的情况下,

public partial class MainWindow : Window, IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // dispose managed resources
            if (BackgroundWorker != null)
            {
                BackgroundWorker.Dispose(); or BackgroundWorker.Close();
                BackgroundWorker = null;
            }
            // Dispose remaining objects,
        }
    }



}

忽略此警告是安全的。

出于正式原因,Backgroundworker 和 DataTable 都实现了 IDisposable,它们实际上并不需要它。

此外,您的 MainWindow 具有(定义)应用程序的生命周期,因此无论如何都不会有资源泄漏。

如果你想要形式上正确并遵守所有规则,那么只需将 IDisposable 添加到你的 MainWindow class。有一个片段。

正如其他人已经读到的那样,在现实生活中这不太可能成为问题,因为:

  • 一旦 MainWindow 未被使用,应用程序很可能即将退出。
  • 给定的两个 类 并不需要 Dispose() 调用它们,如果它们的 USEFULL 生命周期与应用程序相同。
  • 如果 MainWindow 未与默认的 wpf 行为一起使用,则应重命名它以表明它不是。然后根据使用方式考虑寿命问题。
  • 在应用程序存在时进行不必要的清理对用户没有帮助,因为它会减慢退出速度,并且可能会不必要地调入许多内存页面。

由于 MainWindow 是 System.Windows.Window 的子类,因此可以在 Closed event/method 而不是 Dispose() 中进行清理,但这很可能除非您从 OnClosed().

调用 Dispose(),否则不会停止警告

只要让 MainWindow 实现 IDisposable 就会让警告消失,但是你需要问 Dispose() 如何在 MainWindow 上被调用?

但是,如果您希望将代码分析作为日常开发的一部分,则必须停止误报,否则您将不会注意到重要警告。如果是这样,抗租赁路径是在 MainWindow.

上实施 IDisposable