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

时间:2015-06-22 10:37:55

标签: c# wpf code-analysis fxcop

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

  

CA1001拥有一次性领域的类型应为一次性工具   'MainWindow'上的IDisposable,因为它创建了   以下IDisposable类型:'BackgroundWorker','DataTable'。如果   'MainWindow'之前已经发布,增加了实施的新成员   这种类型的ID可被视为对现有的重大改变   消费者。 yesMonitor MainWindow.xaml.cs 38

用于主窗口代码:

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

这些警告应该是什么原因?

4 个答案:

答案 0 :(得分:2)

  

这不是一个简单的问题,因为MainWindow是一个在WPF应用程序中具有特殊含义的类。

我觉得你在这里让自己感到困惑。 MainWindow只是另一个类。恰好在应用程序启动时它会被打开。但是,这是默认行为可以更改

查看App.xaml文件,您会看到StartupUri属性设置为MainWindow,如果需要,可以更改此内容。

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

  

拥有一次性字段的类型应为一次性在'MainWindow'上实现IDisposable,因为它创建了以下IDisposable类型的成员...

我不是IDisposable原则和架构的专家,但你应该在需要的地方实现它。

有关如何正确实施IDisposable的指导,请参阅documentation

答案 1 :(得分:2)

忽略此警告是安全的。

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

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

如果您想要正式并且遵守所有规则,那么只需将IDisposable添加到您的MainWindow类。有一个代码片段。

答案 2 :(得分:1)

您需要在MainWindow上实现IDisposable。实际上你在MainWindow类中有一些需要关闭的资源。当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,
        }
    }



}

答案 3 :(得分:0)

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

  • 一旦MainWindow未被使用,很可能该应用程序即将退出。
  • 如果两个给定的类的USEFULL生命周期与应用程序相同,则它们实际上不需要Dispose()调用它们。
  • 如果MainWindow没有使用默认的wpf行为,则应该重命名它以明确它不是。然后可以考虑终身问题,具体取决于它的使用方式。
  • 在应用程序存在时执行不需要的清理对用户没有帮助,因为它会降低退出速度,并且可能会不必要地在许多页面的内存中进行分页。

由于MainWindow是System.Windows.Window的子类,因此可以在Closed事件/方法而不是Dispose()中进行清理,但这很可能不会停止警告除非您从Dispose()致电OnClosed()

仅仅MainWindow实施IDisposable会使警告消失,但您需要询问Dispose()将如何调用MainWindow

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