Link to home
Start Free TrialLog in
Avatar of gillgates
gillgates

asked on

Creating a Disposable Class

I am trying to create a class that is disposable and I am not sure that I am doing it correctly.

This class basically is a wrapper to write an event to the event log.

Below is my code.  The code works and my program runs using the class, but I don't know if I did the disposable part correctly.  Basically I don't know if it is really disposing.

public class EventHandle: IDisposable
      {
            private GblVar gv;
                      private bool disposed = false;
            private Component Components;
            public EventHandle(string strLocation, string strEventMessage, System.Diagnostics.EventLogEntryType errorType)
            {
                  try
                  {
                        string strEventText = strLocation + " - " + strEventMessage;

                        System.Diagnostics.EventLog ev = new System.Diagnostics.EventLog();

                        if(!System.Diagnostics.EventLog.SourceExists("AppName"))
                        {
                              System.Diagnostics.EventLog.CreateEventSource(gv.strErrorLogSource, "Application");
                        }

                        ev.Source = gv.strErrorLogSource;
                        ev.WriteEntry(strEventText, errorType);
                        ev = null;
                        strEventText = null;
                  }
                  catch(Exception E)
                  {
                        MessageBox.Show("Error in EventHandle() - " + E.ToString());
                  }
            }            
            #region IDisposable Members

            public void Dispose()
            {
                  GC.SuppressFinalize(this);
            }
            protected virtual void Dispose(bool disposing)
            {
                  // Check to see if Dispose has already been called.
                  if(!this.disposed)
                  {
                        if(disposing)
                        {
                              // Dispose managed resources.
                              Components.Dispose();
                        }
                  }
            }
                  
            #endregion
      }


---------------------------------------------------------

I want to then use it like this.

using(EventHandle evh = new EventHandle("main", "test", System.Diagnostics.EventLogEntryType.Information))
                  {}
ASKER CERTIFIED SOLUTION
Avatar of NipNFriar_Tuck
NipNFriar_Tuck

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of NipNFriar_Tuck
NipNFriar_Tuck

Doh... almost forgot... be sure to set the class variable disposed to true inside the if disposing condition.
Avatar of gillgates

ASKER

I get an "An unhandled exception of type 'System.NullReferenceException' occurred in app.exe    Additional information: Object reference not set to an instance of an object."

On this line...

Components.Dispose();
Ah... I normally will chack an object before disposing it to keep this from happening like:

if ( Components != null  && Components.Count > 0 ) {
    Components.Dispose();
}
Do you really want to implement IDisposable for this class? There is no gain in implementing it if your class will not use unmanaged resources. For example, since the Components collection will always be null.

Being able to use a using statement is nice, granted, since it looks clean. However, performance / memory wise you will have no use for it. I can imagine it could even mean a performance hit. It will have to run through the whole Dispose() method while there's absolutely nothing happening.

Regards,

Razzie
Razzie

So if I don't make it disposable, then what do I do with the object when I am done using it?  Just set it to null?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
What Razzie says is true, however there are circumstances that you need to be aware of...

1) If you use unmanaged resources you need to clean these up.  (Razzie statied this earlier).
a) If you use database connections, datareaders, etc... these need to be cleaned up as you can end up with a defunc connection for a period of time if you do not...
b) If you open stream of any sort... these need to be cleaned up.

Even if you are using the DotNET classes for the stream or db classes you should make sure you close/dipose of these particular classes.  Consequently, if you are using the resources at the class level you will probably want to implement the IDisposable with the Disposable Pattern; for local resources you can use a try{ } catch { } finally { // Do clean up here } type of construct.
That is true, unless you use your streams or conncetion within a using clause already:

class MyClass
{

   private void someMethod()
   {
      using(StreamReader sr = new StreamReader())
      {
          // code
      }
   }
}


In the above example, there is no need to implement IDisposable, since the using clause is compiled to a try - finally, calling the Dispose() method in the finally block.