WPF代码分析:拥有可丢弃字段的CA1001类型应该是可丢弃的

本文关键字:类型 CA1001 代码 字段 拥有 WPF | 更新日期: 2023-09-27 17:57:26

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

CA1001拥有一次性字段的类型应为一次性机具IDisposable在"MainWindow"上,因为它创建以下IDisposable类型:"BackgroundWorker"、"DataTable"。如果"MainWindow"以前已发布,添加了实现可用于此类型的ID被认为是对现有ID的突破性更改消费者。yes监视器主窗口.xaml.cs 38

主窗口代码:

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

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

WPF代码分析:拥有可丢弃字段的CA1001类型应该是可丢弃的

忽略此警告是安全的。

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

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

如果您希望形式正确并遵守所有规则,那么只需将IDisposable添加到MainWindow类中即可。这里有一个片段。

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

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

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

MainWindow没有什么特别之处,它不是WPF所需要的某种超级重要的内置神圣救世主,见鬼,如果你愿意,你甚至可以删除它。由于它只是另一个类,所以它应该遵循与其他类相同的原则。在您的案例中,您正在创建实现IDisposable的类的实例,因此,在类中实现IDisposable也是一种很好的做法,可以处理实例。否则,垃圾收集器可能会忽略它们,您可能会发现内存泄漏。请参阅以下消息:

拥有可丢弃字段的类型应该是"MainWindow"上的可丢弃Implement IDisposable,因为它创建了以下IDisposaable类型的成员。。。

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

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

您需要在MainWindow上实现IDisposable。实际上,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,
        }
    }

}

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

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

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

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

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