Form.ShowDialog() and dispose

守給你的承諾、 提交于 2019-12-14 03:43:33

问题


If I have a method like this:

public void Show()
{
   Form1 f = new Form1();
   f.ShowDialog();
}

Do I still need to call dispose on the form even though it will go out of scope, which will be eligible for garbage collection.

From some testing, calling this Show() multiple times .. at some point it seems like the GC collects it since I can see the memory spiking then it goes down at some point in time.

From MSDN it seems to say you MUST call dispose when the form is not needed anymore.


回答1:


In your specific example, no, it's unlikely that it would be particularly useful. Forms do not hold onto a significant amount of resources, so if it takes a little bit longer for some portion of it's code to get cleaned up it isn't going to cause a problem. If that form just happens to be holding onto a control that is used to, say, play a video, then maybe it's actually holding onto some significant number of resources, and if you actually do dispose of those resources in the dispose method then it's worth taking the time to call dispose. For 99% of your forms though, their Dispose method will be empty, and whether you call it or not is unlikely to have any (or any noticeable) effect on your program.

The reason that it's there is primarily to enable the ability to dispose of resources in those 1% of cases where it's important.

It's also worth noting that when a Form is closed its Dispose method is already being called. You would only ever need to add a using or explicit Dispose call if you want to dispose of a Forms resources before that form is closed. (That sounds like a generally bad idea to me). This is easy enough to test. Just create a project with two forms. Have the second form attach an event handler to the Disposing event and show a message box or something. Then when you create an instance of that form and show it (as a dialog or not) you'll see that when you close it the message box will pop up right away, even if you keep the 'Form' instance around and without you ever needing to add a using or Dispose call.




回答2:


What tends to happen is if the item has purely managed resources, calling dispose is not necessarily required, but is strongly advised because it makes disposal deterministic. It isn't always required (in a technical sense) because those managed resources would likely themselves now be eligible for GC, or there is actually nothing to dispose by default and it's an extensibility point.

For unmanaged resources, the Dispose Pattern advises implementing a finalizer, which will be called on GC. If types do not implement the finalizer and dispose is not called, then it is possible (well, very likely) that resources would be left unhandled. Finalizers are the last chance offered by the runtime for clearing your stuff up - they are also time-limited.

Note, that it does not make GC or managed memory reclamation deterministic, disposal is not delete from C++. A disposed item could be a long way away from actually being collected. However, in the managed world, you don't care about deterministic collection, only resource management - in other words, disposal.

That said, I always make sure I call Dispose or use a using statement if a type is disposable, regardless of whether it uses managed or unmanaged resources - it is the expected convention:

public void Show()
{
    using (var f = new Form1())
    {
        f.ShowDialog();
    } // Disposal, even on exceptions or nested return statements, occurs here.
}

Update:

After a discussion with Servy I feel I have to express this point as the reasoning behind my advice of disposing where possible. In the case of MemoryStream, it is clearly a disposable type, but actually does not dispose of anything currently.

Relying on this, however, is to rely on the implementation of MemoryStream. Were this to change to include an unmanaged resource, this would then mean that a reliance on MemoryStream not having anything to dispose becomes problematic.

Where possible (as is the case with IDisposable) I prefer to rely on the public contract. Working against the contract in this instance would mean I am safe from underlying implementation changes.




回答3:


Although you rarely have to manually dispose in C# imo, you could try it like this:

    public void Show()
    {
       using (Form1 f = new Form1())
       {
         f.ShowDialog();
       }
    }

Then at the last accolade of the using part it will get disposed of automatically.




回答4:


You could simply do:

using (var f = new Form1())
   f.ShowDialog();



回答5:


If you want to explicitly dispose, use

 using(Form1 f = new Form1()){

            f.ShowDialog();
        }

This ensures Dispose() is called, as well as it occurs immediately




回答6:


ShowDialog has side effect of keeping the GDI objects alive. In order to avoid GDI leak we need to dispose the ShowDialog appropriately. Where as Show method does not have any implication and GDI will be released appropriately. It is recommended to dispose the showDialog and do not rely on Garbage collector.



来源:https://stackoverflow.com/questions/11454291/form-showdialog-and-dispose

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!