Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. This is why I am starting to loathe programming

This is why I am starting to loathe programming

Scheduled Pinned Locked Moved The Lounge
phpvisual-studiocom
82 Posts 31 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L leppie

    It's like the blind leading the blind.... http://stackoverflow.com/questions/2926869/c-do-you-need-to-dispose-of-objects-and-set-them-to-null/2926877#2926877[^] I think I will get similar responses from here too though :sigh:

    xacc.ide
    IronScheme - 1.0 RC 1 - out now!
    ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x))) The Scheme Programming Language – Fourth Edition

    L Offline
    L Offline
    leonej_dt
    wrote on last edited by
    #49

    I loathe programming as well, but for completely different reasons. I loathe programming because of programmers. Programmers are lazy, stupid and don't understand abstractions, even when they leak. Manage resources frustrate me. Manage resource tedious. Me hate manage resources. Me invent garbage collect. Ooga, booga, garbage collect! Some resources can't garbage collect. Cleanup some resources can't automate. Cleanup some resources need intelligence. Same class both managed resources unmanaged resources. Me confused. Ooga, booga, me confused! Programmers deserve to be punished by making them program ERPs in assembly (optimizing CPU cycles, of course) and efficient operating systems in Scheme.

    If you can play The Dance of Eternity (Dream Theater), then we shall make a band.

    1 Reply Last reply
    0
    • V Vikram A Punathambekar

      OK, let me put it in a slightly different way: If MS had implemented it Piebald's way, how would we be worse off?

      Cheers, Vikram. (Got my troika of CCCs!)

      C Offline
      C Offline
      Chris Trelawny Ross
      wrote on last edited by
      #50

      If every object supported IDisposable, then there would be no easy way to know which really needed it and which didn't - so it would be impossible to know which to wrap in a using block and which could safely be used without one. Personally, I'm glad that only things that need to be disposed implement IDisposable.

      1 Reply Last reply
      0
      • P peterchen

        By implementing IDisposable, the class creator explicitely told you to call Dispose(). If the documentation of a class said "You need to call Init() before using an instance of this class", would you reply with "Ah, I don#t feel like it today"?

        Agh! Reality! My Archnemesis![^]
        | FoldWithUs! | sighist | µLaunch - program launcher for server core and hyper-v server.

        C Offline
        C Offline
        CurtainDog
        wrote on last edited by
        #51

        If the class creator wants it to be used in a particular way then they can build a factory for it. Up until that point I'll use the class however I want to.

        P 1 Reply Last reply
        0
        • L leppie

          It's like the blind leading the blind.... http://stackoverflow.com/questions/2926869/c-do-you-need-to-dispose-of-objects-and-set-them-to-null/2926877#2926877[^] I think I will get similar responses from here too though :sigh:

          xacc.ide
          IronScheme - 1.0 RC 1 - out now!
          ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x))) The Scheme Programming Language – Fourth Edition

          C Offline
          C Offline
          CurtainDog
          wrote on last edited by
          #52

          Don't take it too personally, sometimes being right is an ends in itself.

          1 Reply Last reply
          0
          • F Fabio Franco

            I beleive that too, but leppie is saying we shouldn't call Dispose as the finalizer will always do that for us. In the experiment I proposed, if we don't call Dispose, some handles will be left behind after a few repeated calls of the form's ShowDialog method, even after collection occurs. My point is, call Dispose always and don't rely on finalizer or garbage collection as you can run into trouble. Calling the Form's Dispose method eliminates the extra handles problem, that was my point.

            A Offline
            A Offline
            Andrew Rissing
            wrote on last edited by
            #53

            If you're stating that the extra handles are dangling around waiting for the finalizer to kick in, sure you are correct. You're not leaking memory at all, but rather leaving around objects that can be free'd (to use a C++ term) immediately. If you elaborate on your code a little, it'll prove that the finalizer is called just non-deterministically in your original code:

            public partial class Form1 : Form
            {
                public Form1()
                {
                    InitializeComponent();
                }
            
                private void ShowForm()
                {
                    TestForm frm = new TestForm();
                    frm.ShowDialog();
                    //frm.Dispose();
                }
            
                private void button1\_Click(object sender, EventArgs e)
                {
                    this.ShowForm();
            
                    GC.Collect();
                    GC.WaitForFullGCComplete();
                    GC.WaitForPendingFinalizers();
            
                    this.Text = HWndCounter.GetWindowHandlesForCurrentProcess().ToString();
                }
            
                public class HWndCounter
                {
                    \[DllImport("kernel32.dll")\]
                    private static extern IntPtr GetCurrentProcess();
            
                    \[DllImport("user32.dll")\]
                    private static extern uint GetGuiResources(IntPtr hProcess, uint uiFlags);
            
                    public static int GetWindowHandlesForCurrentProcess()
                    {
                        IntPtr processHandle = GetCurrentProcess();
                        uint userObjects = GetGuiResources(processHandle, 1); // 1 for User resource, disregard GDI
            
                        return Convert.ToInt32(userObjects);
                    }
                }
            
                public class TestForm : Form
                {
                    ~TestForm()
                    {
                        try
                        {
                            Trace.Write("TestForm #" + FormHandle + " finalized.\\r\\n");
                        }
                        catch { }
                    }
            
                    private int FormHandle;
            
                    protected override void OnShown(EventArgs e)
                    {
                        base.OnShown(e);
            
                        try
                        {
                            FormHandle = this.Handle.ToInt32();
                            Trace.Write("TestForm #" + FormHandle + " shown.\\r\\n");
                        }
                        catch { }
                    }
            
                    protected override void OnClosed(EventArgs e)
                    {
                        base.OnClosed(e);
            
                        try
                        {
                            Trace.Write("TestForm #" + FormHandle + " closed.\\r\\n");
                        }
                        catch { }
                    }
            
            F 1 Reply Last reply
            0
            • L leppie

              peterchen wrote:

              the class creator explicitely told you to call Dispose().

              No, he actually said: 'If you want to cleanup the resources immediately, then call Dispose(), but if you forget or dont want to, I'll do it anyways when the object finalizer is called.'

              xacc.ide
              IronScheme - 1.0 RC 1 - out now!
              ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x))) The Scheme Programming Language – Fourth Edition

              X Offline
              X Offline
              xenry
              wrote on last edited by
              #54

              Well this is actually not quite true, as a class that implements IDisposable is not required to have a finalizer.

              1 Reply Last reply
              0
              • F Fabio Franco

                I beleive that too, but leppie is saying we shouldn't call Dispose as the finalizer will always do that for us. In the experiment I proposed, if we don't call Dispose, some handles will be left behind after a few repeated calls of the form's ShowDialog method, even after collection occurs. My point is, call Dispose always and don't rely on finalizer or garbage collection as you can run into trouble. Calling the Form's Dispose method eliminates the extra handles problem, that was my point.

                G Offline
                G Offline
                gnop
                wrote on last edited by
                #55

                I agree, I always call the dispose method if implemented. I couldn't find the handle leak in your test app. The handles do increase but when a GC collection occurs (for me I had to create about 30 dialogs) the count returns to what it was initially?? This is because the finalize method is executed which in turn calls dispose.

                F 1 Reply Last reply
                0
                • A Andrew Rissing

                  If you're stating that the extra handles are dangling around waiting for the finalizer to kick in, sure you are correct. You're not leaking memory at all, but rather leaving around objects that can be free'd (to use a C++ term) immediately. If you elaborate on your code a little, it'll prove that the finalizer is called just non-deterministically in your original code:

                  public partial class Form1 : Form
                  {
                      public Form1()
                      {
                          InitializeComponent();
                      }
                  
                      private void ShowForm()
                      {
                          TestForm frm = new TestForm();
                          frm.ShowDialog();
                          //frm.Dispose();
                      }
                  
                      private void button1\_Click(object sender, EventArgs e)
                      {
                          this.ShowForm();
                  
                          GC.Collect();
                          GC.WaitForFullGCComplete();
                          GC.WaitForPendingFinalizers();
                  
                          this.Text = HWndCounter.GetWindowHandlesForCurrentProcess().ToString();
                      }
                  
                      public class HWndCounter
                      {
                          \[DllImport("kernel32.dll")\]
                          private static extern IntPtr GetCurrentProcess();
                  
                          \[DllImport("user32.dll")\]
                          private static extern uint GetGuiResources(IntPtr hProcess, uint uiFlags);
                  
                          public static int GetWindowHandlesForCurrentProcess()
                          {
                              IntPtr processHandle = GetCurrentProcess();
                              uint userObjects = GetGuiResources(processHandle, 1); // 1 for User resource, disregard GDI
                  
                              return Convert.ToInt32(userObjects);
                          }
                      }
                  
                      public class TestForm : Form
                      {
                          ~TestForm()
                          {
                              try
                              {
                                  Trace.Write("TestForm #" + FormHandle + " finalized.\\r\\n");
                              }
                              catch { }
                          }
                  
                          private int FormHandle;
                  
                          protected override void OnShown(EventArgs e)
                          {
                              base.OnShown(e);
                  
                              try
                              {
                                  FormHandle = this.Handle.ToInt32();
                                  Trace.Write("TestForm #" + FormHandle + " shown.\\r\\n");
                              }
                              catch { }
                          }
                  
                          protected override void OnClosed(EventArgs e)
                          {
                              base.OnClosed(e);
                  
                              try
                              {
                                  Trace.Write("TestForm #" + FormHandle + " closed.\\r\\n");
                              }
                              catch { }
                          }
                  
                  F Offline
                  F Offline
                  Fabio Franco
                  wrote on last edited by
                  #56

                  I get what you're saying, but have you noticed that if you don't call Dispose, even with that solution, one handle gets left behind? Put this: this.Text = HWndCounter.GetWindowHandlesForCurrentProcess().ToString(); before ShowDialog() And then test it commenting and uncommenting the frm.Dispose() without calling Dispose, with your code, I get 42 handles. Calling dispose, I get 41. What it seems to me is that after the finalizer gets called, it still does not free the handle (even calling Dispose method inside the finalizer). I also noticed, that if I call the form's Dispose method from the calling method, the finalizer does not get called. Bottom line is that I never get to reclaim the handle without explicitly Disposing it on the calling method. Even after repeatedly executing this after closing the form: GC.Collect(); GC.WaitForFullGCComplete(); GC.WaitForPendingFinalizers(); I feel there's still something missing I'm not seeing... But to be on the safe side, I still recommend everyone, always call Dispose method if the class implements IDisposable

                  A 1 Reply Last reply
                  0
                  • F Fabio Franco

                    using "using", certifies that the Dispose method gets called on classes that implement IDisposable interface. You don't really need to use it as long as you call Dispose method manually. The most common example is the Window Handle of the Form class. If you use ShowDialog to view a form and don't call the Dispose method, the handle will not be released even when the Form is GCed. GC does not handle unmanaged resources automatically, it does not call Dispose method of objects when they are collected, so yes, it can lead to memory leak. This rarely becomes a problem, but I've ran into this once and it was a pain to pinpoint the leak source. Controls also generate handles, if you have an application that creates lots of controls dinamically it's something you should pay a lots of attention. So, if a class implements IDisposable, call Dispose always, to make sure it releases unmanaged resource just in case it uses any.

                    S Offline
                    S Offline
                    sgorozco
                    wrote on last edited by
                    #57

                    Hi Fabio, Sorry, your example is not entirely correct. If you do not call Dispose() on a Form class instance, it will still be disposed (with its underlying window handle properly released) when it's garbage collected. The IDisposable pattern (which is implemented, as far as I know, in all .net Framework classes that hold native resources) takes precisely care of this. The only difference is that you don't know exactly when will the garbage collection occur and since it's triggered by memory allocation pressure, it might take a while for it to actually happen. That's why it's wise to call Dispose(). Cheers! :) Gerardo

                    F 1 Reply Last reply
                    0
                    • F Fabio Franco

                      I get what you're saying, but have you noticed that if you don't call Dispose, even with that solution, one handle gets left behind? Put this: this.Text = HWndCounter.GetWindowHandlesForCurrentProcess().ToString(); before ShowDialog() And then test it commenting and uncommenting the frm.Dispose() without calling Dispose, with your code, I get 42 handles. Calling dispose, I get 41. What it seems to me is that after the finalizer gets called, it still does not free the handle (even calling Dispose method inside the finalizer). I also noticed, that if I call the form's Dispose method from the calling method, the finalizer does not get called. Bottom line is that I never get to reclaim the handle without explicitly Disposing it on the calling method. Even after repeatedly executing this after closing the form: GC.Collect(); GC.WaitForFullGCComplete(); GC.WaitForPendingFinalizers(); I feel there's still something missing I'm not seeing... But to be on the safe side, I still recommend everyone, always call Dispose method if the class implements IDisposable

                      A Offline
                      A Offline
                      Andrew Rissing
                      wrote on last edited by
                      #58

                      It's likely the extra handle is for a Font or Image that is statically allocated, but only done so once it was loaded. So, I wouldn't call that a leak. It is evident by the fact that the object is being disposed and/or finalized, but the overall count is not going up (minus the initial value). As for the finalizer not being called, that's on purpose. When you implement the IDisposable pattern, you're supposed to do the following for the public Dispose method:

                      public void Dispose()
                      {
                      this.Dispose(true);
                      GC.SuppressFinalize(this);
                      }

                      The last line will suppress the finalizer because of two reasons: 1) It's not needed anymore, the finalizer is meant to call dispose in case it wasn't called. 2) Secondly, objects that need finalizing (as seen with our example) are cleaned up at the framework's whim. This can lead to more memory pressure as an object isn't cleaned up in a timely manner. I whole-heartedly agree that if a class implements IDisposable, that you should call it. But it is important to know the underlying reasons behind that and why the IDiposable pattern works (when coded correctly). Essentially, the pattern is in place to prevent a simple oversight from turning into unusable code.

                      A F 2 Replies Last reply
                      0
                      • A Andrew Rissing

                        It's likely the extra handle is for a Font or Image that is statically allocated, but only done so once it was loaded. So, I wouldn't call that a leak. It is evident by the fact that the object is being disposed and/or finalized, but the overall count is not going up (minus the initial value). As for the finalizer not being called, that's on purpose. When you implement the IDisposable pattern, you're supposed to do the following for the public Dispose method:

                        public void Dispose()
                        {
                        this.Dispose(true);
                        GC.SuppressFinalize(this);
                        }

                        The last line will suppress the finalizer because of two reasons: 1) It's not needed anymore, the finalizer is meant to call dispose in case it wasn't called. 2) Secondly, objects that need finalizing (as seen with our example) are cleaned up at the framework's whim. This can lead to more memory pressure as an object isn't cleaned up in a timely manner. I whole-heartedly agree that if a class implements IDisposable, that you should call it. But it is important to know the underlying reasons behind that and why the IDiposable pattern works (when coded correctly). Essentially, the pattern is in place to prevent a simple oversight from turning into unusable code.

                        A Offline
                        A Offline
                        Andrew Rissing
                        wrote on last edited by
                        #59

                        Btw, add the following to the class as well, to help understand the flow of logic:

                                protected override void Dispose(bool disposing)
                                {
                                    base.Dispose(disposing);
                        
                                    Trace.Write("TestForm #" + FormHandle + " disposed.\\r\\n");
                                }
                        
                        1 Reply Last reply
                        0
                        • L leppie

                          Fabio Franco wrote:

                          Wrong, the Finalizer does not assure the release of unmanaged resources, if there is a Dispose method call it. The Dispose method is not called by the garbage collector.

                          If you implement IDisposable incorrectly, and do not call it from the finalizer if not already disposed, you have stupid code.

                          Fabio Franco wrote:

                          Just do a little experiment and see for yourself:

                          I am not even going to bother.

                          Fabio Franco wrote:

                          If you uncomment GC.Collect() and comment Dispose(), it will keep the handle count from growing indefinitely

                          It's up to you how you deal with it. My point still stands, you dont have to do it, it is not a MUST DO OR DIE situation.

                          xacc.ide
                          IronScheme - 1.0 RC 1 - out now!
                          ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x))) The Scheme Programming Language – Fourth Edition

                          S Offline
                          S Offline
                          sgorozco
                          wrote on last edited by
                          #60

                          I agree with Leppie. The IDisposable pattern (when properly implemented) has a safety net that will release native resources even if we didn't call Dispose() or wrapped our instance with a using statement. Garbage collection might take a while to kick in, and yes, it is possible to write an application where garbage collection will never occur, but if you're talking of resource exhaustion, then that means you are constantly creating objects, then THERE is memory pressure and the gc WILL eventually run (unless of course, you are unnecesarily keeping references to objects that should be collected and by doing so, inducing a memory leak). Cheers, Gerardo

                          1 Reply Last reply
                          0
                          • G gnop

                            I agree, I always call the dispose method if implemented. I couldn't find the handle leak in your test app. The handles do increase but when a GC collection occurs (for me I had to create about 30 dialogs) the count returns to what it was initially?? This is because the finalize method is executed which in turn calls dispose.

                            F Offline
                            F Offline
                            Fabio Franco
                            wrote on last edited by
                            #61

                            Commenting and Uncommenting frm.Dispose() makes no difference in handle count? Forcing the collection also won't make a difference?

                            1 Reply Last reply
                            0
                            • S sgorozco

                              Hi Fabio, Sorry, your example is not entirely correct. If you do not call Dispose() on a Form class instance, it will still be disposed (with its underlying window handle properly released) when it's garbage collected. The IDisposable pattern (which is implemented, as far as I know, in all .net Framework classes that hold native resources) takes precisely care of this. The only difference is that you don't know exactly when will the garbage collection occur and since it's triggered by memory allocation pressure, it might take a while for it to actually happen. That's why it's wise to call Dispose(). Cheers! :) Gerardo

                              F Offline
                              F Offline
                              Fabio Franco
                              wrote on last edited by
                              #62

                              Hi Gerardo, I know that GC can't be predicted, however you can force a collection with GC.Collect() Garbage Collection is no guarantee that Dispose gets called, it all depends on the finalizer implementation. If Dispose correctly releases unmanaged resources and if you call it from the finalizer (good code), then yes, unmanaged resource will be released when a collection occurs, if you don't, Dispose method will never get called and the unmanaged resources will never be reclaimed (not until the process ends). In another discussion in this topic I provide an example of exactly that, where the Window handle is not released even after forcing collection (finalizer gets called, you can see it throug output windows). Only way it did was through explicitly calling Dispose method afer the form was closed, inside the calling method. Regards, Fábio

                              S 1 Reply Last reply
                              0
                              • A Andrew Rissing

                                It's likely the extra handle is for a Font or Image that is statically allocated, but only done so once it was loaded. So, I wouldn't call that a leak. It is evident by the fact that the object is being disposed and/or finalized, but the overall count is not going up (minus the initial value). As for the finalizer not being called, that's on purpose. When you implement the IDisposable pattern, you're supposed to do the following for the public Dispose method:

                                public void Dispose()
                                {
                                this.Dispose(true);
                                GC.SuppressFinalize(this);
                                }

                                The last line will suppress the finalizer because of two reasons: 1) It's not needed anymore, the finalizer is meant to call dispose in case it wasn't called. 2) Secondly, objects that need finalizing (as seen with our example) are cleaned up at the framework's whim. This can lead to more memory pressure as an object isn't cleaned up in a timely manner. I whole-heartedly agree that if a class implements IDisposable, that you should call it. But it is important to know the underlying reasons behind that and why the IDiposable pattern works (when coded correctly). Essentially, the pattern is in place to prevent a simple oversight from turning into unusable code.

                                F Offline
                                F Offline
                                Fabio Franco
                                wrote on last edited by
                                #63

                                Andrew Rissing wrote:

                                It's likely the extra handle is for a Font or Image that is statically allocated, but only done so once it was loaded. So, I wouldn't call that a leak. It is evident by the fact that the object is being disposed and/or finalized, but the overall count is not going up (minus the initial value).

                                Ok, but why does the count comes down when the form's Dispose method is called from the calling method, and not from the finalizer? I mean if it is something static, it should not come down either way right? This is what's boggling me. Thank you for your clarifications, it surely filled a few gaps. Still, there is this thing, bothering me... Did you get to reproduce what I was saying?

                                A 1 Reply Last reply
                                0
                                • F Fabio Franco

                                  Hi Gerardo, I know that GC can't be predicted, however you can force a collection with GC.Collect() Garbage Collection is no guarantee that Dispose gets called, it all depends on the finalizer implementation. If Dispose correctly releases unmanaged resources and if you call it from the finalizer (good code), then yes, unmanaged resource will be released when a collection occurs, if you don't, Dispose method will never get called and the unmanaged resources will never be reclaimed (not until the process ends). In another discussion in this topic I provide an example of exactly that, where the Window handle is not released even after forcing collection (finalizer gets called, you can see it throug output windows). Only way it did was through explicitly calling Dispose method afer the form was closed, inside the calling method. Regards, Fábio

                                  S Offline
                                  S Offline
                                  sgorozco
                                  wrote on last edited by
                                  #64

                                  Hi Fabio, Yes, you are correct, good code should follow the IDisposable pattern documented by Microsoft, that way you can dispose unmanaged resources early if you want, or leave it to the GC. I'll look at your example, because if what you say is true, then Microsoft is not following its own recommended patterns! Thanks for the reply, Gerardo

                                  F 1 Reply Last reply
                                  0
                                  • S sgorozco

                                    Hi Fabio, Yes, you are correct, good code should follow the IDisposable pattern documented by Microsoft, that way you can dispose unmanaged resources early if you want, or leave it to the GC. I'll look at your example, because if what you say is true, then Microsoft is not following its own recommended patterns! Thanks for the reply, Gerardo

                                    F Offline
                                    F Offline
                                    Fabio Franco
                                    wrote on last edited by
                                    #65

                                    Thanks Gerardo, yes the point was exactly that, and I prefer not to rely on the Finalizer implementation, simply call Dispose and play the safe side.

                                    1 Reply Last reply
                                    0
                                    • F Fabio Franco

                                      Andrew Rissing wrote:

                                      It's likely the extra handle is for a Font or Image that is statically allocated, but only done so once it was loaded. So, I wouldn't call that a leak. It is evident by the fact that the object is being disposed and/or finalized, but the overall count is not going up (minus the initial value).

                                      Ok, but why does the count comes down when the form's Dispose method is called from the calling method, and not from the finalizer? I mean if it is something static, it should not come down either way right? This is what's boggling me. Thank you for your clarifications, it surely filled a few gaps. Still, there is this thing, bothering me... Did you get to reproduce what I was saying?

                                      A Offline
                                      A Offline
                                      Andrew Rissing
                                      wrote on last edited by
                                      #66

                                      Indeed, I was able to reproduct it. I don't know though if its a memory leak or just something else we aren't aware of. If it was a true memory leak, I would imagine that it's behavior would be repeatable and the allocations would keep rising. Ultimately, one handle is pretty insignificant in the grand scheme of things.

                                      F 1 Reply Last reply
                                      0
                                      • A Andrew Rissing

                                        Indeed, I was able to reproduct it. I don't know though if its a memory leak or just something else we aren't aware of. If it was a true memory leak, I would imagine that it's behavior would be repeatable and the allocations would keep rising. Ultimately, one handle is pretty insignificant in the grand scheme of things.

                                        F Offline
                                        F Offline
                                        Fabio Franco
                                        wrote on last edited by
                                        #67

                                        Yes, this keeps me thinking that this is just one case, for one form. What else might have this behaviour? and depending on the scenario, this might rise significantly. So I have no doubt that calling Dispose (when you desire to release resources of course) is a very strong should, no matter how the Garbage Collector gets invoked. One theory I have about this behaviour is that one of these handles is kept for performance issues. When Dispose does not get called and the object is collected, the Garbage Collector (or the Finalizer / IDisposable implementation) might think it will be reused (instatiated again at some point of time) and so the handle is kept for reuse with the same form. If you experiment a little more, you'll also notice that another handle increment will happen if you instatiate another Form implementation (besides from TestForm) and don't call Dispose. Same thing will happen for that form. Anyways, this was a nice discussion to have. Regards, Fábio

                                        A 1 Reply Last reply
                                        0
                                        • L leppie

                                          It's like the blind leading the blind.... http://stackoverflow.com/questions/2926869/c-do-you-need-to-dispose-of-objects-and-set-them-to-null/2926877#2926877[^] I think I will get similar responses from here too though :sigh:

                                          xacc.ide
                                          IronScheme - 1.0 RC 1 - out now!
                                          ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x))) The Scheme Programming Language – Fourth Edition

                                          B Offline
                                          B Offline
                                          bjarneds
                                          wrote on last edited by
                                          #68

                                          Looking at all the responses in this thread, there seem to be a lot of confusion about dispose and finalization. The basic recommendations is really not that complicated :-\ : 1) In the finalizer (i.e. ~SomeClass() ), clean up unmanaged resources. This method is called by the garbage collector, when the object can no longer be reached. However, it may not happen immediately, the garbage collector waits until it needs memory (which could be hours or days after it is no longer reachable). 2) In Dispose() (i.e. the method defined in IDisposable), cleanup managed and unmanaged resources. Furthermore, call GC.SuppressFinalize(this) (since everything is now cleaned up, there is no need for the finalizer to be called by the garbage collector, and doing this optimizes the garbage collection). The dispose pattern furthermore combines the implementation of these two, by implementing a protected Dispose(bool disposing) in the base class. The finalizer calls it with false, the Dispose() in IDisposable calls it with true. This makes it simple for derived classes, it only has to override this method and add whatever it needs, but it doesn't really change anything, it just a matter of style in the implementation. Why shouldn't the finalizer clean up managed resources as well? Because that is what the garbage collector does - managed resources is the memory used by other managed classes. Furthermore, it is very limited what a finalizer is allowed to do - it must not use references to other objects (as they may already be garbage collected). Why implement Dispose(), if the garbage collector takes care of it all? Because sometimes you need some cleanup to take place at a deterministic time, not hours or days later. The classical example is an open file. You typically want to allow the file being opened again, immediately you are done using it. Why do you need IDisposable for this, why not just implement a Close method on the class? Because with IDisposable, you have a uniform way of dealing with scenarios like this (e.g. a using block). You are free to implement a Close method as well if it feels more natural to use this name - this would simply call Dispose(). Are there any other reasons for Dispose() than deterministic cleanup (or: are there any situations where you have to call Dispose())? Yes (and this is where it gets a little more complicated :doh: ). If the object you no longer need is referenced by a longer living object, it may unintentionally keep it alive. Y

                                          C 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups