简体   繁体   中英

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

in my WPF application code i got the following Warnings:

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

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.

I think you are confusing yourself here. MainWindow is just another class. 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.

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. 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. 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...

I am no expert in IDisposable principles and architecture, but you should implement this where it's needed.

See the documentation on guidance of how to implement IDisposable properly.

It is safe to ignore this warning.

Both Backgroundworker and DataTable implement IDisposable for formal reasons, they don't really need it.

Besides, your MainWindow has (defines) the lifetime of the application so there is no resource leakage anyway.

If you want to be formally correct and stick to all the rules, then just add IDisposable to your MainWindow class. There is a snippet for that.

You need to implement IDisposable on MainWindow. Actually you have some resources in MainWindow class which needs to be closed. They are not closed when MainWindow will be destroyed. To achieve this, we implement IDisposable and in the implementation we dispose these objects.

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.
  • 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.
  • If MainWindow is not being used with the default wpf behaviour, it should be renamed to make it clear that it is not. 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() .

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 ?

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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