How can I find if a TextWriter / StreamWriter is disposed?

  • Thread starter Thread starter Zytan
  • Start date Start date
Z

Zytan

There is no IsDisposed() method. I could just access it, and catch
ObjectDisposedException, but that seems ugly.

Zytan
 
Hello Zytan,

What are u gonna reproduce? Maybe usin' WeakReference helps u?

---
WBR, Michael Nemtsev [C# MVP].
My blog: http://spaces.live.com/laflour
Team blog: http://devkids.blogspot.com/

"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo

Z> There is no IsDisposed() method. I could just access it, and catch
Z> ObjectDisposedException, but that seems ugly.
Z>
Z> Zytan
Z>
 
Zytan said:
There is no IsDisposed() method. I could just access it, and catch
ObjectDisposedException, but that seems ugly.

I've never been in the situation where I have a reference to something
but don't know whether or not it's been disposed - what's your
situation? Can you avoid it somehow?
 
If it has a Dispose method and it is implemented according to the recommended
pattern, you can call the Dispose method without concern whether it is
Disposed or not, catching the ObjectDisposed exception.

How could we expect to call an "IsDisposed" method on an object that is no
longer there? I'm not sure that makes any sense.

Cheers,
Peter
 
Peter Bromberg said:
If it has a Dispose method and it is implemented according to the recommended
pattern, you can call the Dispose method without concern whether it is
Disposed or not, catching the ObjectDisposed exception.

How could we expect to call an "IsDisposed" method on an object that is no
longer there? I'm not sure that makes any sense.

It does - disposed != not there. Something can certainly be disposed of
while there are still references to it, and you could conceivably want
to make sure you don't call other methods (eg Write) on something which
is disposed. I'd argue that it's best not to get into such a situation
in the first place though.
 
Zytan said:
There is no IsDisposed() method. I could just access it, and catch
ObjectDisposedException, but that seems ugly.

I do not know if it is "supported" but the following both
seems to work and do make some sense:

sw.BaseStream != null && sw.BaseStream.CanWrite

(actually that is IsNotDisposed() but who cares)

Arne
 
I do run into such situations in asynchronous Socket Callbacks. Try/Catch
keeps application running, but I am uneasy about this.

Michael
 
Arne Vajhøj said:
I do not know if it is "supported" but the following both
seems to work and do make some sense:

sw.BaseStream != null && sw.BaseStream.CanWrite

(actually that is IsNotDisposed() but who cares)

Arne


This will throw a NullReferenceException when called on a disposed sw or sr .
What you actually want is this:

if(sw != null && sw.BaseStream != null)
// go ahead, the underlying resource is still accessible.
else
...

Anyway, I do prefer to handle the ObjectDisposedException.

Willy.
 
Hello Zytan,
What are u gonna reproduce? Maybe usin' WeakReference helps u?

In my logger, sometimes Finalizers want to call MyLogger.WriteLine()
and by this time, the underlying stream is already closed by the
framework. So, I want to see if it is closed (disposed) or not, so I
can re-open it, to make these last second Write's.

The easy way is to try catch ObjectDisposedException. I thought maybe
there's a prettier way.

Zytan
 
I do run into such situations in asynchronous Socket Callbacks. Try/Catch
keeps application running, but I am uneasy about this.

That's my thought. Perhaps I am just not comfortable with exceptions,
since they are for exceptional behaviour. But, maybe this is such a
thing.

Zytan
 
In my logger, sometimes Finalizers want to call MyLogger.WriteLine()

That's where the problem is. Finalizers are designed to clean up
unmanaged state they know about - and nothing else. As soon as they
start relying on other things being present, you *will* run into
issues.

Personally, I can't remember the last time I wrote a finalizer. Cast
off your C++ idioms :)

Jon
 
It does - disposed != not there. Something can certainly be disposed of
while there are still references to it, and you could conceivably want
to make sure you don't call other methods (eg Write) on something which
is disposed.
Yes.

I'd argue that it's best not to get into such a situation
in the first place though.

Sometimes, its unavoidable. The run time of finalizers are almost
chaotic. And the framework closes file streams before the finalizer
of my own class that holds the only reference to the file stream has
been invoked, so there's nothing else I can do. I know loggers are an
extreme case, since they have to run at all times, and this is
unusual.

Zytan
 
What you actually want is this:
if(sw != null && sw.BaseStream != null)
// go ahead, the underlying resource is still accessible.
else
...

Anyway, I do prefer to handle the ObjectDisposedException.

Given the above code or the exception, I take the exception any day.
At least I know for 100% certainty that it will work, and it doesn't
rely on me understanding or typing the code example correctly.

Zytan
 
In my logger, sometimes Finalizers want to call MyLogger.WriteLine()
That's where the problem is. Finalizers are designed to clean up
unmanaged state they know about - and nothing else. As soon as they
start relying on other things being present, you *will* run into
issues.

That makes sense.
Personally, I can't remember the last time I wrote a finalizer. Cast
off your C++ idioms :)

To be honest, the finalizer is just for the purposed of seeing when it
is run, but since other people are using my logger class, and told me
that it wasn't working when called inside such finalizers, I figured
I'd make it work. And it does by catching the ObjectDisposedException
exception, re-opening, appending, closing the file. But, I thought
there would be a better way.

It's hard to say how some people may use the logger class. Maybe just
to print stats temporarily for debugging? Who knows. After all, it's
just a logger, and it can be viewed after the program is done, and it
is one of those things that you think conceptually can be called from
anywhere, even before your main functions are run, during construction
of static class data members. But, yes, I also can't see a reason for
production code to have a finalizer, as well.

Zytan
 
Hello Zytan,

You should take into account that CLR does not guarantee that finalizers
will be called at all.

Read this http://groups.google.com/group/micr...read/thread/ff6a616884dcee08/83f2a3b55dbb8935
I suppose it exactly what are u trying to reproduce

---
WBR, Michael Nemtsev [C# MVP].
My blog: http://spaces.live.com/laflour
Team blog: http://devkids.blogspot.com/

"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo
Z> In my logger, sometimes Finalizers want to call MyLogger.WriteLine()
Z> and by this time, the underlying stream is already closed by the
Z> framework. So, I want to see if it is closed (disposed) or not, so I
Z> can re-open it, to make these last second Write's.
Z>
Z> The easy way is to try catch ObjectDisposedException. I thought
Z> maybe there's a prettier way.
Z>
Z> Zytan
Z>
 
You should take into account that CLR does not guarantee that finalizers
will be called at all.

Really? I fail to understand why.
Read this http://groups.google.com/group/microsoft.public.dotnet.languages.csha...
I suppose it exactly what are u trying to reproduce

No, not really, I just know that maybe some people will call my logger
class from their finalizers, and will wonder why the WriteLine's
didn't work (since the logger's file stream has been closed by the
CLR). So, I just wanted to make such calls re-open, append, close the
file in the case that the file stream is already closed.

I couldn't see from that thread where it says that there is no
guarantee that finalizers are called.

Zytan
 
Hello Zytan,

Because CLR has timeout for finalizing and only single finalized thread is
used, which can be stalled somewhere.

http://msdn.microsoft.com/msdnmag/issues/07/01/ManagedLeaks/default.aspx?loc=en


---
WBR, Michael Nemtsev [C# MVP].
My blog: http://spaces.live.com/laflour
Team blog: http://devkids.blogspot.com/

"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo
Z> Really? I fail to understand why.
Z>
 
Zytan said:
Given the above code or the exception, I take the exception any day.
At least I know for 100% certainty that it will work, and it doesn't
rely on me understanding or typing the code example correctly.

Zytan

Hmmm.... Didn't you notice that this was a reply to Arne, and that I was correcting his
sample?

Willy.
 
What you actually want is this:
Hmmm.... Didn't you notice that this was a reply to Arne, and that I was correcting his
sample?

Yes.

My reply meant that if given 2 choices: A. Arne's code (the correct
version), or B. handle ObjectDisposedException, I would choose B over
A any day. Because: for A to work, I have to make sure my code is
written correctly, and this is easy to screw up, especially for
someone not well versed in which properties to call, and it allows for
easy syntax errors that may be missed even when skimming over it. B,
on the other hard, is pretty much fool proof. It's hard to mess up an
exception handler for a specific exception.

In other words, my preference is the same as yours.

Zytan
 

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

Back
Top