473,321 Members | 1,708 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,321 software developers and data experts.

IDisposable, "using" keyword and "Close()" methods

Hi all,
coming from an unmanaged programming background, I took my time to
sort out the IDisposable and finalizer patterns. Just when I thought
I had it all conceptually neatly arranged, the "Close()" methods reared
their ugly (at least it would seem...)heads.

I was happily delving away in the .NET framework, investigating the
stream classes with the msdn and Lutz Roeder's .NET reflector, when I
stumbled upon the following:

(using BinaryReader as an example, though not the only "bad guy")
1) The MSDN : "This implementation of Close calls the Dispose method
passing a true value."
2) the Close() method in the BinaryReader is marked virtual
3) the "using" keyword will invoke the implemented IDisposable.Dispose()
on the expression you want to dispose

it looks to me like the "using" keyword in this case could be
potentially very dangerous. Nothing prevents me from descending from
BinaryReader, override the Close() method, and do some essential extra
work (marking a flag, log something, whatever), and everyone using my
class with the "using" keyword would have (at best) unnoticed side effects.

I can see the need for IDisposable, I can see the need for virtual
methods that will call Dispose on your behalf, but I don't get the need
for a "using" keyword for calling Dispose() for you, when (at least in
some cases) you might be short-circuiting things because you should've
called "Close()" (or whatever they choose to call it). The documentation
in the MSDN doesn't mention anywhere (that is, I couldn't find it...)
that you should use Close() instead of
Dispose() from the implemented interface.

Is (or should I mark) the "using" keyword "potentially dangerous"?

Thanks in advance,

Willem van Rumpt
Nov 16 '05 #1
7 2982
Willem van Rumpt <no***********@no.thelandslide.spam.com> wrote:

<snip>
Is (or should I mark) the "using" keyword "potentially dangerous"?


No - failing to use "using" is potentially dangerous.

If you want to write a class which doesn't implement Dispose
appropriately - i.e. if calling Dispose isn't enough to clean up the
unmanaged resources - that's fine. There's nothing to stop you from
writing badly behaved classes in .NET - but it *is* relatively easy to
write *well*-behaved classes instead.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #2
Hi Willem,

Close methods is added to stream, reader, writer, etc classes just because
it makes more sense for those classes to be closed. Why is it virtual?
Simply because normally when somethig work with streams the idea is to
abstract where the data actually goes it could be memory, disk, db, etc. So
normaly the code deals with the base class. In .NET disposing is the way to
release unmanaged resources, so you should write your classes with that in
mind.
Some times Close behaves differently according to some conditions. For
example look at the Form class. When the form is shown modalles calling
Close dispose the form object. When the form is shown as a modal dialog,
though, Close hides the form and doesn't destroyed (disposed) it.
One is sure thing, though, Dispose always destroy. So bare this in mind when
you write your classes

--
HTH
Stoitcho Goutsev (100) [C# MVP]
"Willem van Rumpt" <no***********@no.thelandslide.spam.com> wrote in message
news:uK**************@TK2MSFTNGP12.phx.gbl...
Hi all,
coming from an unmanaged programming background, I took my time to
sort out the IDisposable and finalizer patterns. Just when I thought
I had it all conceptually neatly arranged, the "Close()" methods reared
their ugly (at least it would seem...)heads.

I was happily delving away in the .NET framework, investigating the
stream classes with the msdn and Lutz Roeder's .NET reflector, when I
stumbled upon the following:

(using BinaryReader as an example, though not the only "bad guy")
1) The MSDN : "This implementation of Close calls the Dispose method
passing a true value."
2) the Close() method in the BinaryReader is marked virtual
3) the "using" keyword will invoke the implemented IDisposable.Dispose()
on the expression you want to dispose

it looks to me like the "using" keyword in this case could be
potentially very dangerous. Nothing prevents me from descending from
BinaryReader, override the Close() method, and do some essential extra
work (marking a flag, log something, whatever), and everyone using my
class with the "using" keyword would have (at best) unnoticed side effects.
I can see the need for IDisposable, I can see the need for virtual
methods that will call Dispose on your behalf, but I don't get the need
for a "using" keyword for calling Dispose() for you, when (at least in
some cases) you might be short-circuiting things because you should've
called "Close()" (or whatever they choose to call it). The documentation
in the MSDN doesn't mention anywhere (that is, I couldn't find it...)
that you should use Close() instead of
Dispose() from the implemented interface.

Is (or should I mark) the "using" keyword "potentially dangerous"?

Thanks in advance,

Willem van Rumpt

Nov 16 '05 #3
Jon Skeet [C# MVP] wrote:
Willem van Rumpt <no***********@no.thelandslide.spam.com> wrote:

<snip>
Is (or should I mark) the "using" keyword "potentially dangerous"?

No - failing to use "using" is potentially dangerous.

If you want to write a class which doesn't implement Dispose
appropriately - i.e. if calling Dispose isn't enough to clean up the
unmanaged resources - that's fine. There's nothing to stop you from
writing badly behaved classes in .NET - but it *is* relatively easy to
write *well*-behaved classes instead.

I'm not talking unmanaged resources. I'm assuming that the Dispose()
part would be properly implemented, i.e. releasing all unmanaged
resources, BUT since the Close() method is virtual, it seems the class
can still work and have a function and a state which the Close() method
sets or invokes, which would not be invoked or set if using the "using"
keyword, even more, it has been explicitly marked "virtual" so
descendants can do their own thing before/after calling dispose.

From what you say, I think that I didn't grasp the meaning of
IDisposable correctly. Should I regard a "disposable" object as
"destroyed", not to be referenced again?.

Willem van Rumpt

Nov 16 '05 #4
Hi,

Just override Dispose(bool) and there put your code. Like this:

using System;
using System.IO;

namespace Test {

public class TestReader : BinaryReader {

public TestReader(Stream stream) : base(stream)
{
}

protected override void Dispose(bool disposing)
{
Console.WriteLine("Dispose called.");
base.Dispose(disposing);
}
}

public class Test {
[STAThread]
public static void Main()
{
TestReader testReader = new TestReader(new MemoryStream());
testReader.Close();
}
}
}

Sunny

In article <uK**************@TK2MSFTNGP12.phx.gbl>,
no***********@no.thelandslide.spam.com says...
Hi all,
coming from an unmanaged programming background, I took my time to
sort out the IDisposable and finalizer patterns. Just when I thought
I had it all conceptually neatly arranged, the "Close()" methods reared
their ugly (at least it would seem...)heads.

I was happily delving away in the .NET framework, investigating the
stream classes with the msdn and Lutz Roeder's .NET reflector, when I
stumbled upon the following:

(using BinaryReader as an example, though not the only "bad guy")
1) The MSDN : "This implementation of Close calls the Dispose method
passing a true value."
2) the Close() method in the BinaryReader is marked virtual
3) the "using" keyword will invoke the implemented IDisposable.Dispose()
on the expression you want to dispose

it looks to me like the "using" keyword in this case could be
potentially very dangerous. Nothing prevents me from descending from
BinaryReader, override the Close() method, and do some essential extra
work (marking a flag, log something, whatever), and everyone using my
class with the "using" keyword would have (at best) unnoticed side effects.

I can see the need for IDisposable, I can see the need for virtual
methods that will call Dispose on your behalf, but I don't get the need
for a "using" keyword for calling Dispose() for you, when (at least in
some cases) you might be short-circuiting things because you should've
called "Close()" (or whatever they choose to call it). The documentation
in the MSDN doesn't mention anywhere (that is, I couldn't find it...)
that you should use Close() instead of
Dispose() from the implemented interface.

Is (or should I mark) the "using" keyword "potentially dangerous"?

Thanks in advance,

Willem van Rumpt

Nov 16 '05 #5
Willem van Rumpt <no***********@no.thelandslide.spam.com> wrote:
If you want to write a class which doesn't implement Dispose
appropriately - i.e. if calling Dispose isn't enough to clean up the
unmanaged resources - that's fine. There's nothing to stop you from
writing badly behaved classes in .NET - but it *is* relatively easy to
write *well*-behaved classes instead.
I'm not talking unmanaged resources. I'm assuming that the Dispose()
part would be properly implemented, i.e. releasing all unmanaged
resources, BUT since the Close() method is virtual, it seems the class
can still work and have a function and a state which the Close() method
sets or invokes, which would not be invoked or set if using the "using"
keyword, even more, it has been explicitly marked "virtual" so
descendants can do their own thing before/after calling dispose.


For some classes, there may be things you can do with an object after
calling Close, but before calling Dispose.

It's interesting to note that Stream is rather different from
BinaryWriter - Dispose calls Close rather than the other way round.
From what you say, I think that I didn't grasp the meaning of
IDisposable correctly. Should I regard a "disposable" object as
"destroyed", not to be referenced again?.


When an object is disposed, it should usually either be ready to reuse
"from scratch" or shouldn't be reused at all - usually the latter.
Calling Dispose should be all that is required when one is finished
with an object, and it's very rare (IME) that it's good to call it
*before* one is finished with the object.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #6
LMFAO!!!

--
HTH

Kyril Magnos

"Richard" <Ri*****@discussions.microsoft.com> wrote in message
news:C4**********************************@microsof t.com...
|> Nothing prevents me from descending from
| > BinaryReader, override the Close() method, and do some essential extra
| > work (marking a flag, log something, whatever), and everyone using my
| > class with the "using" keyword would have (at best) unnoticed side
effects.
| >
|
| The IDisposable pattern wants you to do all of your extra work in the
overriden method aka "protected override void Dispose(bool disposing)". If
you put your extra work in there then the "using" keyword will work fine as
the keyword is going to call "void Dispose()" witch is implemented to call
your overriden "Dispose(true)" - hence doing your extra work...
|
| > Is (or should I mark) the "using" keyword "potentially dangerous"?
| >
|
| Don't forget that "using" is syntactically equivalent to try{}
finally{Dispose} so it's a good idea to use it. Actually I think the whole
IDispose thing is LAAAAMMMMMEEE! As a C++ guy I really really want a .NET
keyword "delete" that is defined as: immediately calls the object's
finalizer {if one exists} and then issues a GC.SuppressFinalizer() for the
object...
|
| But nooo nobody listens to me... Nope! I thought going into Iraq was a
dumb idea - all I wanted to do was confiscate Saudi Arabian oil and kick the
natives out into their endless beach. If we'd done that gas would be .10
per gallon, we would have flipped UBL the big time finger by confiscating
holy land, the Wahhabiist movement would have lost its funding, and we'd
have a HUGE base right next to Saddam Hussein while leaving HIM in token
power so that he can deal with the Iraqi people. But nooooo.... I get no
delete keyword and now I'm stuck with an estimated $30,000 per taxpayer bill
for a dumb headed plan to make the middle east safe for Israel....
|
| Nope nobody ever listens to me and that's why the world's a Flippin
mess...
|
|
|
|
|
Nov 16 '05 #7
Richard <Ri*****@discussions.microsoft.com> wrote:
Don't forget that "using" is syntactically equivalent to try{}
finally{Dispose} so it's a good idea to use it. Actually I think the
whole IDispose thing is LAAAAMMMMMEEE! As a C++ guy I really really
want a .NET keyword "delete" that is defined as: immediately calls
the object's finalizer {if one exists} and then issues a
GC.SuppressFinalizer() for the object...


That doesn't allow for situations where an object can be reused, of
course, which Dispose allows for in theory, even if it's rarely used.

You'd also still want another keyword in order to put the delete within
a try/finally block automatically, IMO.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: smitty mittlebaum | last post by:
I have a strange problem that has reared its ugly head in the last few weeks. I have the option "Compact on Close" (Tools, Options, General tab) enabled on my development machine. I did this...
19
by: Lauren Wilson | last post by:
A2K app: Question: is the flagged line (<<<) below necessary. If that line is needed, what effect does it have (if any) on the fact that the very same database is the linked back end db? ...
2
by: Paul LAURENT | last post by:
Hi everybody, I am using the STL "ofstream" class. I open a file using "ofstream" in update at the end mode ("ate"), I can read and write my file correctly. => What I would like to do is...
4
by: Philipp Sumi | last post by:
Hello all I have a thread that performs some simple I/O within a loop that runs on a separate thread. I used the using keyword to ensure the writer's disposal: using (writer) { while...
5
by: lindanr | last post by:
In ASP.NET 2005 I have an onblur="window.close()" javascript event in the <body> tag. When I click on the window's scrollbar, the window closes. The same code works fine in ASP.NET 2003. Any...
4
by: R.A.M. | last post by:
Hello, (Sorry for my English...) I am learning C# and I have a question: is it good practice to use "using", for example: using (SqlConnection connection = new SqlConnection(ConnectionString))...
30
by: Pep | last post by:
Is it best to include the code "using namespace std;" in the source or should each keyword in the std namespace be qualified by the namespace tag, such as std::cout << "using std namespace" <<...
2
by: R.A.M. | last post by:
Hello, I have started larning C# and I have a question concerning "using (...)" keyword. For example: using (SqlConnection connection = new SqlConnection(ConnectionString)) {...
2
by: Steven W. Orr | last post by:
>From the tutorial, they said that the following construct will automatically close a previously open file descriptor: ------------------- #! /usr/bin/python import sys for nn in range ( 1,...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.