|
|
|
date: Tue, 19 Aug 2008 16:29:54 -0500,
group: microsoft.public.dotnet.framework
back
Checking if an object has already been Disposed
Hi All,
Is there any simple way to check if a particular object has had dispose
called on it already?
I'm working with some Image objects and I need to know if they've had their
Dispose method called. I've Googled, I've looked at methods on the GC, I've
looked at WeakReferences, but nothing seems to fit the bill. It seems like
such a straightforward requirement, but I can't seem to find out how to
accomplish it effectively.
The closest I've come so far is either:
Try
Dim someVar = myImage.VerticalResolution
Catch
ImageIsDisposed = True
End Try
Which of course is very slow because I'm relying on exceptions being thrown
to make an assumption.
The other solution I came up with was to use reflection and check the
internal "nativeImage" variable of the Image object to see if that =
IntPtr.Zero. Again, because it's reflection, it's slow. First solution is
extremely slow when the image *has* been disposed, whereas reflection is
much faster, but the reflection solution is much slower when the image has
*not* been disposed. So I'm stuck between the devil and the deep blue sea.
It would be really nice if there were some kind of "Image.IsDisposed" public
readonly property. In fact, that would've been nice for *all* IDisposable
objects.
Anyone got a better solution?
date: Tue, 19 Aug 2008 16:29:54 -0500
author: Alex Clark ail
Re: Checking if an object has already been Disposed
On Tue, 19 Aug 2008 14:29:54 -0700, Alex Clark <quanta@noemail.noemail>
wrote:
> [...]
> The closest I've come so far is either:
>
> Try
> Dim someVar = myImage.VerticalResolution
> Catch
> ImageIsDisposed = True
> End Try
>
> Which of course is very slow because I'm relying on exceptions being
> thrown
> to make an assumption.
>
> The other solution I came up with was to use reflection and check the
> internal "nativeImage" variable of the Image object to see if that =
> IntPtr.Zero. Again, because it's reflection, it's slow. First solution
> is
> extremely slow when the image *has* been disposed, whereas reflection is
> much faster, but the reflection solution is much slower when the image
> has
> *not* been disposed. So I'm stuck between the devil and the deep blue
> sea.
>
> It would be really nice if there were some kind of "Image.IsDisposed"
> public
> readonly property. In fact, that would've been nice for *all*
> IDisposable
> objects.
>
> Anyone got a better solution?
Well, the best solution is to not try to use objects that have been
disposed. If you can shed some light as to how you got into this
situation in the first place, it might be possible to offer more detailed
advice that would more properly address the issue.
Personally, I would not use the reflection-based approach at all. It's
too fragile. You could speed it up by caching the FieldInfo instance for
the type, but that doesn't fix the problem that the internal data
structure could change any time.
As far as the exception being "too slow", have you checked performance
when not running the debugger? It's true that exceptions are slow
generally, but they are especially painful when the debugger is attached
to the process.
The very best approach would be to not write code that can access disposed
objects in the first place. Performance-wise, the next best approach
would be something where you have control either over the code that
creates, disposes, and/or otherwise uses the object. Then you could
either make a flag, or even wrap the Image object in a container object
that tracks the disposal state (but you'd have to make sure you can change
the code doing the disposing so that it always goes through the wrapper).
But maintenance-wise, if you can't fix the code so that it's not trying to
access disposed objects in the first place, I think catching exceptions is
the next-best. Only if performance is absolutely unacceptable would I
think something else would be warranted, and you should check the
performance with a "Release" build without the debugger attached.
Pete
date: Tue, 19 Aug 2008 15:12:38 -0700
author: Peter Duniho
Re: Checking if an object has already been Disposed
Hi Peter,
Yeah, I know the pattern itself doesn't seem to make much sense, but it's
for a library which will be supplied to others and works with images. There
are blocks which work with images where it can't be assumed that the image
hasn't yet been disposed, but it needs to behave gracefully in that
scenario. It's working fine with exception handling (and yes - it does
perform much better when in Release mode) but I was hoping there was a more
efficient way to check for that.
When you consider that Control and its descendants all have a .IsDisposed
property, I was just hoping that Image might've implemented something
similar. I can live with it the way it is though.
Thanks for your help,
Alex
"Peter Duniho" wrote in message
news:op.uf5mncq58jd0ej@petes-computer.local...
> On Tue, 19 Aug 2008 14:29:54 -0700, Alex Clark <quanta@noemail.noemail>
> wrote:
>
>> [...]
>> The closest I've come so far is either:
>>
>> Try
>> Dim someVar = myImage.VerticalResolution
>> Catch
>> ImageIsDisposed = True
>> End Try
>>
>> Which of course is very slow because I'm relying on exceptions being
>> thrown
>> to make an assumption.
>>
>> The other solution I came up with was to use reflection and check the
>> internal "nativeImage" variable of the Image object to see if that =
>> IntPtr.Zero. Again, because it's reflection, it's slow. First solution
>> is
>> extremely slow when the image *has* been disposed, whereas reflection is
>> much faster, but the reflection solution is much slower when the image
>> has
>> *not* been disposed. So I'm stuck between the devil and the deep blue
>> sea.
>>
>> It would be really nice if there were some kind of "Image.IsDisposed"
>> public
>> readonly property. In fact, that would've been nice for *all*
>> IDisposable
>> objects.
>>
>> Anyone got a better solution?
>
> Well, the best solution is to not try to use objects that have been
> disposed. If you can shed some light as to how you got into this
> situation in the first place, it might be possible to offer more detailed
> advice that would more properly address the issue.
>
> Personally, I would not use the reflection-based approach at all. It's
> too fragile. You could speed it up by caching the FieldInfo instance for
> the type, but that doesn't fix the problem that the internal data
> structure could change any time.
>
> As far as the exception being "too slow", have you checked performance
> when not running the debugger? It's true that exceptions are slow
> generally, but they are especially painful when the debugger is attached
> to the process.
>
> The very best approach would be to not write code that can access disposed
> objects in the first place. Performance-wise, the next best approach
> would be something where you have control either over the code that
> creates, disposes, and/or otherwise uses the object. Then you could
> either make a flag, or even wrap the Image object in a container object
> that tracks the disposal state (but you'd have to make sure you can change
> the code doing the disposing so that it always goes through the wrapper).
>
> But maintenance-wise, if you can't fix the code so that it's not trying to
> access disposed objects in the first place, I think catching exceptions is
> the next-best. Only if performance is absolutely unacceptable would I
> think something else would be warranted, and you should check the
> performance with a "Release" build without the debugger attached.
>
> Pete
date: Thu, 21 Aug 2008 14:35:38 -0500
author: Alex Clark ail
|
|