locked
Difference between using statement and Dispose/Finalize RRS feed

  • Question

  • Hi,

    I know what is the difference between dispose and finalize but i got confused between using statement and dispose/finalize.Both do the same thing then why we have these two concept for the same thing.Please help me one this.I searched in the google but didnt find anything.Any help will be much appreciated.

    Tuesday, March 15, 2011 5:40 AM

Answers

  • Let me explain. See the below class. (This is not proper class but should give an overall idea)

    class DataManagement: IDisposable
    {
       public delegate void SortRecordsDelegate();
       SortRecordsDelegate recordSort;
    
       public DataManagement()
       {
          recordSort = new SortRecordsDelegate(BeginSortRecords);
       }
    
       public void BeginSortRecords()
       {
          recordSort.BeginInvoke(...);
       }
    
       public void EndSortRecords()
       {
          ...
          recordSort.EndInvoke(...);
       }
    
       public void SortAllRecordsInTable()
       {
          //This function sorts all records in a table
       }
    
       public void Dispose()
       {
          recordSort = null;
       }
    }
    

     In this class, you can notice 2 important methods 1. BeginSortRecords 2. EndSortRecords. The BeginSortRecords method calls the delegate asynchronously And call to EndSortRecords will fetch the result from delegate. Now consider below class which consumes the above class.

    class DBClient
    {
       DataManagement dbObject;
    
       public void SortRecordsAsync()
       {
          using ( dbObject = new DataManagement() )
          {
              dbObject.BeginSortRecords();
          }
       }
    
       public void DisplaySortedRecord()
       {
          dbObject.EndSortRecords();
       }
    }
    

    Obseve the above class. SortRecordsAsync function calls BeginSortRecords which in turn invokes the delegate asynchronously. But, after calling function, dbObject is disposed which inturn will dispose the delegate. Now when you call DisplaySortedRecord() function, it will call EndSortRecords function. The EndSortRecords will try to call EndInoke on the delegate but the delegate is already disposed !!!! And it will throw the exception.

    So what is the mistake here? We surrouned dbObject with using and when it comes out of using, dbObject dispose is called which we never intended to call. So, we can re-write the DBClient as,

    class DBClient
    {
       DataManagement dbObject;
    
       public void SortRecordsAsync()
       {
          dbObject.BeginSortRecords();
       }
    
       public void DisplaySortedRecord()
       {
          dbObject.EndSortRecords();
       }
    }
    

    Hope you understand this concept. 


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    • Marked as answer by sdfgfdgfd Saturday, March 31, 2012 1:36 AM
    Tuesday, March 15, 2011 11:35 AM
  • Yes, that is correct. Apart from that,

    1. To use using block, the object must have implemented IDisposable. If not, you cannot use 'using' over creating the object. On the other hand, if the object contains a method called Dispose (or a similar method which performs cleanup), you can call that method to dispose the object.

    2. using ensures you have the object is disposed immediately when using block is executed. You can always replace using block with a call to Dispose().

    3. If you are performing some ASynchronous opertations, then 'using' is may cause some serious problems. This case, you got to call Dispose()

    4. One last silly thing - if you use 'using' it takes 2 to 3 lines. But calling Dispose take just a single line :)

    I am not saying 'using' is not preferred. The only advantage is it always disposes the object (even when an exception is there in using block). On the other hand, if you want to call Dispose(), then make sure you call it at appropriate places.

    I hope this gives you an idea.


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    • Marked as answer by Paul Zhou Wednesday, March 16, 2011 8:44 AM
    Tuesday, March 15, 2011 7:02 AM
  • I got your point.Thanks a lot.
    • Marked as answer by sdfgfdgfd Wednesday, March 16, 2011 4:11 AM
    Wednesday, March 16, 2011 4:11 AM

All replies

  • Using does nothing more than wrap an IDisposable object in a try/finally block to ensure it is disposed of.  It's simply there for convenience (like the ternary operator) since the Dispose pattern is so common.

    ShaneB


    Tuesday, March 15, 2011 6:01 AM
  • Thanks Shane,

    Can i say that using dispose() and "using" statement depends on the lifeline of an object.Because most of the time i have seen implementing using statement in a method.So if we are doing some unmanaged operation in a method which is limited to that method body only then in that case we can use "Using" but if our unmanaged operation implementation is scatered across so many method then we can go for the Dispose().Is that correct some extent??Thanks again.

    Tuesday, March 15, 2011 6:33 AM
  • Yes, that is correct. Apart from that,

    1. To use using block, the object must have implemented IDisposable. If not, you cannot use 'using' over creating the object. On the other hand, if the object contains a method called Dispose (or a similar method which performs cleanup), you can call that method to dispose the object.

    2. using ensures you have the object is disposed immediately when using block is executed. You can always replace using block with a call to Dispose().

    3. If you are performing some ASynchronous opertations, then 'using' is may cause some serious problems. This case, you got to call Dispose()

    4. One last silly thing - if you use 'using' it takes 2 to 3 lines. But calling Dispose take just a single line :)

    I am not saying 'using' is not preferred. The only advantage is it always disposes the object (even when an exception is there in using block). On the other hand, if you want to call Dispose(), then make sure you call it at appropriate places.

    I hope this gives you an idea.


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    • Marked as answer by Paul Zhou Wednesday, March 16, 2011 8:44 AM
    Tuesday, March 15, 2011 7:02 AM
  • Thanks Adavesh,

    i got all the points except 3.Can you please tell me what kind of asynchronous operation talking about and what kind of serious probelm may occur.Can you please explain this point a little more.Thanks

    Tuesday, March 15, 2011 8:56 AM
  • Let me explain. See the below class. (This is not proper class but should give an overall idea)

    class DataManagement: IDisposable
    {
       public delegate void SortRecordsDelegate();
       SortRecordsDelegate recordSort;
    
       public DataManagement()
       {
          recordSort = new SortRecordsDelegate(BeginSortRecords);
       }
    
       public void BeginSortRecords()
       {
          recordSort.BeginInvoke(...);
       }
    
       public void EndSortRecords()
       {
          ...
          recordSort.EndInvoke(...);
       }
    
       public void SortAllRecordsInTable()
       {
          //This function sorts all records in a table
       }
    
       public void Dispose()
       {
          recordSort = null;
       }
    }
    

     In this class, you can notice 2 important methods 1. BeginSortRecords 2. EndSortRecords. The BeginSortRecords method calls the delegate asynchronously And call to EndSortRecords will fetch the result from delegate. Now consider below class which consumes the above class.

    class DBClient
    {
       DataManagement dbObject;
    
       public void SortRecordsAsync()
       {
          using ( dbObject = new DataManagement() )
          {
              dbObject.BeginSortRecords();
          }
       }
    
       public void DisplaySortedRecord()
       {
          dbObject.EndSortRecords();
       }
    }
    

    Obseve the above class. SortRecordsAsync function calls BeginSortRecords which in turn invokes the delegate asynchronously. But, after calling function, dbObject is disposed which inturn will dispose the delegate. Now when you call DisplaySortedRecord() function, it will call EndSortRecords function. The EndSortRecords will try to call EndInoke on the delegate but the delegate is already disposed !!!! And it will throw the exception.

    So what is the mistake here? We surrouned dbObject with using and when it comes out of using, dbObject dispose is called which we never intended to call. So, we can re-write the DBClient as,

    class DBClient
    {
       DataManagement dbObject;
    
       public void SortRecordsAsync()
       {
          dbObject.BeginSortRecords();
       }
    
       public void DisplaySortedRecord()
       {
          dbObject.EndSortRecords();
       }
    }
    

    Hope you understand this concept. 


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    • Marked as answer by sdfgfdgfd Saturday, March 31, 2012 1:36 AM
    Tuesday, March 15, 2011 11:35 AM
  • I got your point.Thanks a lot.
    • Marked as answer by sdfgfdgfd Wednesday, March 16, 2011 4:11 AM
    Wednesday, March 16, 2011 4:11 AM
  •  Hi sdfgfdgfd,

    Please always mark only those posts which answered your question. That will encourage the people who answer your question. Because, the post you marked here as answer is not an answer.

    Thanks.


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    • Marked as answer by sdfgfdgfd Saturday, March 31, 2012 1:36 AM
    • Unmarked as answer by sdfgfdgfd Saturday, March 31, 2012 1:36 AM
    Wednesday, March 16, 2011 5:08 AM