using(object) ??


D

Duggi

I used to wonder why MS implemented C# to accept the following code

using (Font f = new Font())
{
// some code here.
}

While the same can be achieved through

{
Font f = new Font()
// some code here.
}

Just making code as a block and create the object inside the block.
Why MS took pain to implement the semantics to understand in C# it as
in first block.

As per my understanding the above code does the following things
1. Creates a block where f is used
2. When code block completes execution, f is garbage collected.

I was wrong. There is one major significant difference between the two
code blocks.

Actually, what ever the object used in the using(object) statement,
has to implement IDisposable. I think by now you got the difference.
The beauty of the using(object) statement is that after the execution
of the using block object.Dispose() will be called by the framework,
releasing all the unmanaged resources.

See below code:

class TestC : IDisposable
{
public void UseLimitedResource()
{
Console.WriteLine("Using limited resource...");
}

void IDisposable.Dispose()
{
// this class uses significant unmanaged resources and are relesed
here.
Console.WriteLine("Disposing limited resource.");
}
}


class Program
{
static void Main(string[] args)
{
using (TestC testC = new TestC())
{
testC.UseLimitedResource();
}

Console.ReadLine();
}
}

However I ran into another BIG doubt that why C# allows the following
code

class Program
{
static void Main(string[] args)
{
TestC testC = new TestC()
using (testC)
{
testC.UseLimitedResource();
}

testC.UseLimitedResource();

Console.ReadLine();
}
}

Object is already disposed, still you can use it, driving to CRASHing
your own applications????


I appriciate your help to continue this...

-Cnu
 
Ad

Advertisements

P

Peter Morris

class TestC : IDisposable
{
private bool IsDisposed = false; //******

public void UseLimitedResource()
{
Console.WriteLine("Using limited resource...");
}

protected virtual void Dispose(bool disposing)
{
if (IsDisposed)
throw new ObjectDisposedException();

Console.WriteLine("Disposing limited resource.");
IsDisposed = true;
GC.SuppressFinalize(this);
}

void IDisposable.Dispose()
{
Dispose(true);
}

~TestC()
{
Dispose(false);
}

}
 
J

Jon Skeet [C# MVP]

Peter Morris said:
class TestC : IDisposable
{
private bool IsDisposed = false; //******

public void UseLimitedResource()
{
Console.WriteLine("Using limited resource...");
}

protected virtual void Dispose(bool disposing)
{
if (IsDisposed)
throw new ObjectDisposedException();

Console.WriteLine("Disposing limited resource.");
IsDisposed = true;
GC.SuppressFinalize(this);
}

void IDisposable.Dispose()
{
Dispose(true);
}

~TestC()
{
Dispose(false);
}

}

One issue with this: Dispose() shouldn't throw an exception when called
multiple times. From MSDN:

<quote>
If an object's Dispose method is called more than once, the object must
ignore all calls after the first one. The object must not throw an
exception if its Dispose method is called multiple times. Instance
methods other than Dispose can throw an ObjectDisposedException when
resources are already disposed.
</quote>

Personally I usually just seal the class and implement IDisposable
"simply" (and without a finalizer). The above more general pattern is
rarely necessary unless you're in complicated situations, IMO.
 
D

Duggi

 class TestC : IDisposable
 {
    private bool IsDisposed = false; //******

    public void UseLimitedResource()
    {
        Console.WriteLine("Using limited resource...");
    }

    protected virtual void Dispose(bool disposing)
    {
        if (IsDisposed)
            throw new ObjectDisposedException();

        Console.WriteLine("Disposing limited resource.");
        IsDisposed = true;
        GC.SuppressFinalize(this);
    }

    void IDisposable.Dispose()
    {
        Dispose(true);
    }

    ~TestC()
    {
        Dispose(false);
    }

 }

thats gre8, implementing a dispose() pattern suggested by MS.

However if my lazy developers does not implement this, and simply went
ahead with the code in the question, there must be a check from
runtime atleast for throwing an exception that object is already
disposed.

-Cnu.
 
D

Duggi

One issue with this: Dispose() shouldn't throw an exception when called
multiple times. From MSDN:

<quote>
If an object's Dispose method is called more than once, the object must
ignore all calls after the first one. The object must not throw an
exception if its Dispose method is called multiple times. Instance
methods other than Dispose can throw an ObjectDisposedException when
resources are already disposed.
</quote>

Personally I usually just seal the class and implement IDisposable
"simply" (and without a finalizer). The above more general pattern is
rarely necessary unless you're in complicated situations, IMO.

--
Jon Skeet - <[email protected]>
Web site:http://www.pobox.com/~skeet 
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com

Hi Jon,

<quote>
If an object's Dispose method is called more than once, the object
must
ignore all calls after the first one. The object must not throw an
exception if its Dispose method is called multiple times. Instance
methods other than Dispose can throw an ObjectDisposedException when
resources are already disposed.
</quote>

Is this by implementing dispose pattern, or by default runtime can do
it?

When I ran the code in the question... It ran perfectly.. without any
exception. I am little worried if any of my busy developers forget to
implement this.

-Cnu
 
J

Jon Skeet [C# MVP]

Duggi said:
<quote>
If an object's Dispose method is called more than once, the object
must
ignore all calls after the first one. The object must not throw an
exception if its Dispose method is called multiple times. Instance
methods other than Dispose can throw an ObjectDisposedException when
resources are already disposed.
</quote>

Is this by implementing dispose pattern, or by default runtime can do
it?

That's when you implement IDisposable.
When I ran the code in the question... It ran perfectly.. without any
exception. I am little worried if any of my busy developers forget to
implement this.

How often do you implement IDisposable yourself? How often do you write
a using statement which *doesn't* declare a variable and create a new
instance of whatever you're using?

A modicum of care is required, but that's all.
 
Ad

Advertisements

D

Duggi

I used to wonder why MS implemented C# to accept the following code [....]

How is this different from the previous thread you started, and which you 
finished up by saying that you got the "zest" of it?

Apologies to all in this thread!!!

Yesterday night I tried asking a question with the title " using
(object) a Mystery for me!!! "

And the groups site displayed an error while posting it... however it
got posted correctly... here is the link
http://groups.google.com/group/micr...27b67698fdc/195000037a06e7b9#195000037a06e7b9

that why I stated a new thread / question.


The other question I had was about the XmlSerialization class... which
I got clarified with you. I am thankful to you for your valuable
replies. They helped me in understanding the XML Serialization class
more properly.

here is the link..
http://groups.google.com/group/micr...2dec0e30337/45ed5934c71ba19e#45ed5934c71ba19e

The current question is about using(object)

-Cnu
 
D

Duggi

That's when you implement IDisposable.


How often do you implement IDisposable yourself? How often do you write
a using statement which *doesn't* declare a variable and create a new
instance of whatever you're using?

A modicum of care is required, but that's all.

--
Jon Skeet - <[email protected]>
Web site:http://www.pobox.com/~skeet 
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com

Thanks Jon,

I understand that Dispose pattern is the solution for the bad code in
question. I really understand the importance of the dispose pattern
now.

Thanks to all of you in the discussion for your valuable time.

-Cnu

PS: I am trying to get myself more and more familier with .Net and C#.
If at all I ask any dumb dumb questions, please understand my level of
expertise.
 
G

Göran Andersson

Duggi said:
<quote>
If an object's Dispose method is called more than once, the object
must
ignore all calls after the first one. The object must not throw an
exception if its Dispose method is called multiple times. Instance
methods other than Dispose can throw an ObjectDisposedException when
resources are already disposed.
</quote>

Is this by implementing dispose pattern, or by default runtime can do
it?

When I ran the code in the question... It ran perfectly.. without any
exception. I am little worried if any of my busy developers forget to
implement this.

-Cnu

According to the guidelines, you should be able to do this:

TestC test = new TestC();
test.Dispose();
test.Dispose();

If the second call to Dispose throws an exception (which the code from
Peter Morris does), it doesn't follow the guidelines.
 
C

Cor Ligthert[MVP]

Duggi,

I strongly get the idea that you have a wrong idea what dispose does.

It releases the unmanaged "resources".

It does not release an object, that is done by the GC. Which surely does not
start when something goes out of scope as you wrote. It is done time by time
which can even be at the end of the program.

A lot of managed code is still only a wrapper around old com objects, as you
see strongly in Sharepoint.
As you are doing something for SharePoint, then it is good practise to use
dispose on every object or use using as that is automaticly done then. The
latter is surely not in general. As you look at most Data (SQL) classes
(including Linq) the dispose does almost nothing, is simple not there or/and
is wrapped in the close method.

Cor
 
P

Peter Morris

Yeah, I was rushing and instead of throwing the exception in the property
getter that read the resource I just wrote the code in the Dispose method.
I think I just saw the words "limited resource" and wrote the code straight
in to throw the exception. :)
 
Ad

Advertisements

D

Duggi

Duggi,

I strongly get the idea that you have a wrong idea what dispose does.

It releases the unmanaged "resources".

It does not release an object, that is done by the GC. Which surely does not
start when something goes out of scope as you wrote. It is done time by time
which can even be at the end of the program.

A lot of managed code is still only a wrapper around old com objects, as you
see strongly in Sharepoint.
As you are doing something for SharePoint, then it is good practise to use
dispose on every object or use using as that is automaticly done then. The
latter is surely not in general. As you look at most Data (SQL) classes
(including Linq) the dispose does almost nothing, is simple not there or/and
is wrapped in the close method.

Cor

Duggi said:
I used to wonder why MS implemented C# to accept the following code
using (Font f = new Font())
{
     // some code here.
}
While the same can be achieved through
{
Font f = new Font()
     // some code here.
}
Just making code as a block and create the object inside the block.
Why MS took pain to implement the semantics to understand in C# it as
in first block.
As per my understanding the above code does the following things
1. Creates a block where f is used
2. When code block completes execution, f is garbage collected.
I was wrong. There is one major significant difference between the two
code blocks.
Actually, what ever the object used in the using(object) statement,
has to implement IDisposable. I think by now you got the difference.
The beauty of the using(object) statement is that after the execution
of the using block object.Dispose() will be called by the framework,
releasing all the unmanaged resources.
See below code:
class TestC : IDisposable
{
       public void UseLimitedResource()
       {
           Console.WriteLine("Using limited resource...");
       }
       void IDisposable.Dispose()
       {
// this class uses significant unmanaged resources and are relesed
here.
           Console.WriteLine("Disposing limited resource.");
       }
}
class Program
{
static void Main(string[] args)
     {
           using (TestC testC = new TestC())
           {
               testC.UseLimitedResource();
           }
           Console.ReadLine();
      }
}
However I ran into another BIG doubt that why C# allows the following
code
class Program
{
static void Main(string[] args)
     {
TestC testC = new TestC()
           using (testC)
           {
               testC.UseLimitedResource();
           }
testC.UseLimitedResource();

           Console.ReadLine();
      }
}
Object is already disposed, still you can use it, driving to CRASHing
your own applications????
I appriciate your help to continue this...

Thanks Cor,

I got one practical use case of the scenario where allowing the above
code makes sense. I understand that a little care is required while
using the object that is disposed. Thanks for throwing light on it.

Thanks
-Cnu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top