简体   繁体   English

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

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

in my WPF application code i got the following Warnings: 在我的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'. 拥有一次性字段的CA1001类型应为“ MainWindow”上的实现IDisposable实施,因为它创建以下IDisposable类型的成员:“ BackgroundWorker”,“ DataTable”。 If 'MainWindow' has previously shipped, adding new members that implement IDisposable to this type is considered a breaking change to existing consumers. 如果“ MainWindow”以前已发货,则将实现IDisposable的新成员添加到此类型被视为对现有使用者的重大更改。 yesMonitor MainWindow.xaml.cs 38 yesMonitor MainWindow.xaml.cs 38

for code of main window: 对于主窗口的代码:

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

what should be the reason for these warning? 这些警告的原因应该是什么?

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是一个在WPF应用程序中具有特殊含义的类,因此这并不是一个看起来简单的问题。

I think you are confusing yourself here. 我认为您在这里感到困惑。 MainWindow is just another class. MainWindow只是另一个类。 It just so happens that it gets opened when the application starts. 恰好发生在应用程序启动时将其打开。 However this is default behavior , it can be changed . 但是,这是默认行为可以更改

Look in the App.xaml file, and you'll see the StartupUri property set to MainWindow , you can change this if you want. 查看App.xaml文件,您会看到StartupUri属性设置为MainWindow ,可以根据需要更改此属性。

There isn't anything special about MainWindow , it isn't some kind of super-important built-in holy messiah that WPF needs, heck, you can even delete it if you want. MainWindow没有什么特别的,它不是WPF所需要的某种超重要的内置圣弥赛亚,哎呀,您甚至可以根据需要将其删除。 As it's just another class, it should follow the same principles as any other class. 由于它只是另一类,因此应遵循与其他任何类相同的原则。 In your case, you are creating instances of classes which implement IDisposable , therefore, it is good practice to implement IDisposable in your class to dispose your instances too. 在您的情况下,您正在创建实现IDisposable的类的实例,因此,在您的类中实现IDisposable来处置您的实例也是一个好习惯。 Otherwise, the garbage collector might ignore them and you may find you will have memory leaks. 否则,垃圾收集器可能会忽略它们,并且您可能会发现内存泄漏。 See the message below: 请参阅以下消息:

Types that own disposable fields should be disposable Implement IDisposable on 'MainWindow' because it creates members of the following IDisposable types... 拥有一次性字段的类型应该在'MainWindow'上是一次性Implement IDisposable,因为它创建以下IDisposable类型的成员...

I am no expert in IDisposable principles and architecture, but you should implement this where it's needed. 我不是IDisposable原则和体系结构方面的专家,但是您应该在需要的地方实现它。

See the documentation on guidance of how to implement IDisposable properly. 请参阅有关如何正确实现IDisposable指导的文档

It is safe to ignore this warning. 可以忽略此警告。

Both Backgroundworker and DataTable implement IDisposable for formal reasons, they don't really need it. 出于正式原因,Backgroundworker和DataTable都实现了IDisposable,但实际上并不需要它。

Besides, your MainWindow has (defines) the lifetime of the application so there is no resource leakage anyway. 此外,您的MainWindow拥有(定义)应用程序的生存期,因此无论如何都不会发生资源泄漏。

If you want to be formally correct and stick to all the rules, then just add IDisposable to your MainWindow class. 如果您想形式正确并遵守所有规则,则只需将IDisposable添加到MainWindow类即可。 There is a snippet for that. 有一个摘要。

You need to implement IDisposable on MainWindow. 您需要在MainWindow上实现IDisposable。 Actually you have some resources in MainWindow class which needs to be closed. 实际上,MainWindow类中有一些资源需要关闭。 They are not closed when MainWindow will be destroyed. 当销毁MainWindow时,它们不会关闭。 To achieve this, we implement IDisposable and in the implementation we dispose these objects. 为了实现这一点,我们实现了IDisposable,并在实现中处理了这些对象。

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

In your case, 就你而言

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,
        }
    }



}

As has already been read by others, in real life this is not likely to be an issue , as: 正如其他人已经读过的, 在现实生活中,这不太可能成为问题 ,因为:

  • Most likely the application is just about to exit once MainWindow is not in use. 一旦不使用MainWindow,应用程序很可能即将退出。
  • The two given classes don't really need Dispose() calling on them, if they have a USEFULL lifetime that is the same as the application. 如果两个给定的类具有与应用程序相同的USEFULL生存期,则它们实际上并不需要调用Dispose()
  • If MainWindow is not being used with the default wpf behaviour, it should be renamed to make it clear that it is not. 如果MainWindow没有与默认的wpf行为一起使用,则应将其重命名以清楚地表明不是。 Then lifetime issues can be considered depending on how it is used. 然后可以根据其使用方式来考虑寿命问题。
  • Doing unneeded cleaning while an application is existing is not helpful to the user, as it slows down the exit and may needlessly page in many pages of memory. 在存在应用程序的同时执行不必要的清理操作对用户没有帮助,因为这会使退出速度变慢,并且可能不必要地在许多内存页面中分页。

As MainWindow is a subclass of System.Windows.Window a case could be made for doing the cleanup in the Closed event/method instead of Dispose() , but that will most likely not stop the warning unless you called Dispose() from OnClosed() . 由于MainWindow是System.Windows.Window的子类,因此可以在Closed事件/方法中代替Dispose()进行清理,但这很可能不会停止警告,除非您从OnClosed() Dispose()调用Dispose()OnClosed()

Just making MainWindow implement IDisposable would make the warning go away, but you then need to ask how will Dispose() get called on the MainWindow ? 仅使MainWindow实现IDisposable就可以消除警告,但是您需要询问如何在MainWindow上调用Dispose()

However if you wish to make the code analytics a part of your day to day development, you must stop false positives, as otherwise you will not notice the important warning. 但是,如果您希望使代码分析成为日常开发的一部分,则必须停止误报,否则您将不会注意到重要的警告。 If so the path of lease resistance is to implement IDisposable on MainWindow . 如果是这样,则抗租约性途径是在MainWindow上实现IDisposable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM