3

I have a small confusion with the IDisposable interface and the using keyword in C# on which classes we could use it.

using (DataSet studentDS = GetMyStudentDS())
{
    // here comes some code
}

I found that Classes inherited from DataSet class are not finalized by the garbage collector, if so is it a good practice to put that in the using block so that it is done manually once its job is done. could someone brief it for the benefit of all. Thanks.

Darren
  • 68,902
  • 24
  • 138
  • 144
user824910
  • 1,067
  • 6
  • 16
  • 38
  • Possible duplicate with http://stackoverflow.com/questions/317184/c-sharp-using-keyword-when-and-when-not-to-use-it – Likurg May 29 '12 at 07:18
  • To clarify the using statement does not force the finalizer to run by the garbage collector. The 'using' statement merely guarantees the Dispose() method of the IDisposable object will run. – trickdev May 29 '12 at 07:20
  • 1
    Dataset is a bit of a special case: http://stackoverflow.com/questions/913228/should-i-dispose-dataset-and-datatable "The Dispose method in DataSet exists ONLY because of side effect of inheritance-- in other words, it doesn't actually do anything useful in the finalization." – HugoRune May 29 '12 at 07:22

6 Answers6

4

is it a good practice to put that in the using block

Yes it is. As DataSet implement IDisposible interface. DataSet extends MarshalByValueComponent class. MarshalByValueComponent class implements IDisposable.

Any derived type will also have IDisposable implemented. If it does not explicitly implements (in other words override IDisposable.Dispose), base method (DataSet.Dispose) will be called.

Regarding the Finalizer, that is a separate concept to make sure that unmanaged resources are cleaned up even if developer fails to call the Dispose method (or forgets using block).

Tilak
  • 30,108
  • 19
  • 83
  • 131
  • having said that it is a good practice to use the Using block for Dataset, Is it like the Garbage Collector Cycle will clear the Dataset in the memory cache at some point later and using block may do that as soon as its job is done? – user824910 May 29 '12 at 07:40
  • 1
    Dispose and Garbage collection are different but related concept. Dispose is usually used for releasing unmanaged resources on which Garbage collector has no role. Garbage collector only handles managed memory. Dataset internally uses some unmanaged resources, which is why it implements Dispose. If you dont specify using block, or forget to call Dispose, then unmanaged resource will not be freed up.The trick (with performance penalty) is to call the [Dispose in finalizer](http://www.c-sharpcorner.com/uploadfile/tkagarwal/memorymanagementinnet11232005064832am/memorymanagementinnet.aspx). – Tilak May 29 '12 at 07:46
  • To your question, if a class implements Dispose, it is good practice to use using block. – Tilak May 29 '12 at 07:47
4

I personally would not use it for a DataSet. I would use a using statement when I would need to close a connection and dispose of it, such as a file reader, database or a SharePoint connection. C# is a managed language and the CLR will take care of garbage collection for you and in a case such as using a DataSet I would still stick with this principle (Let the CLR do it for you).

http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx

http://www.w3enterprises.com/articles/using.aspx

Darren
  • 68,902
  • 24
  • 138
  • 144
  • May be if I handle a huge volume of data in the dataset, is it good to force garbage collection manually. though CLR will handle it calling Garbage collector later at some point? – user824910 May 29 '12 at 07:32
  • IDisposable is not an alternative for GC. "using" statement does not do garbage collection so you should not worry about "who will take care of garbage collection" anyway. – Mert Akcakaya May 29 '12 at 07:52
  • @Mert I know. The using statement disposes of the object and releases all resources used by the MarshalByValueComponent as stated on MSDN. I was stating that I would let the CLR manage the memory, if he wanted to do an immediate garbage collection the OP could do GC.Collect(); – Darren May 29 '12 at 07:58
2

There's a difference between a finalizer (destructor) and the IDisposable pattern. A finalizer is called by the GC at non-deterministic times and is used to clean unmanaged resources associated with the class and free the memory occupied by the instance. It is out of your control when the destructor runs.

IDisposable is used to clean objects at deterministic times. It doesn't free the memory occupied by the object but it is often used to close files, database connections, ...

So the general rule is that if an object implements IDisposable it is good practice to wrap its instances in using keyword in order to release resources as soon as possible.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0

DataSets implement IDisposable, but they supress their Finalization.
So it's really not needed, they do not introduce any unmanaged code.
Do not wrap it with a using statement, however don't forget to use the using keyword around your sql connection or data readers.

Erez Robinson
  • 794
  • 4
  • 9
0

C# allows You to use using on everything that implements IDisposable. Why? Because using is just a syntactic sugar. using(obj){/*somecode*/} is actually something like this:

try
{
    /*somecode*/
}
finally
{
    if(obj!=null) obj.Dispose();
}

If You are using Typed DataSet You might have noticed that your autogenerated class does not override Dispose(bool). So Dispose does nothing to your autogenerated tables and columns. To help your data set free memory (and it realy has problem with it) override Dispose(bool) in your autogenerated TypedDataSet (in partial file). Do something like this:

protected override void Dispose(bool disposing)
{
    foreach (DataTable tab in this.Tables)
    {
        if (tab != null)
        {
            tab.Clear();
            tab.Columns.Clear();
            tab.Dispose();
        }
    }
    this.Tables.Clear();
    base.Dispose(disposing);
}

And now using using on this SataSet will make sense.

Grzegorz W
  • 3,487
  • 1
  • 21
  • 21
-1

Yes, definitely you can use any object initialization code in using block. There is no sideffects of using it. In, whatever scenario if you want to make 100% sure for garbage collection of an object keep it in using block.

shanky
  • 376
  • 1
  • 18
  • Garbage collection and calling Dispose are *not* the same thing at all. Calling `Dispose` (which is what a `using` statement does) doesn't cause the object to be garbage collected. – Jon Skeet May 29 '12 at 07:31