How to determine whether an object is a VALID COM object

A

abhimanyu

I have a method Marshal.IsComObject(...) that returns TRUE if an
object is a COM object.
I have an object of Excel.Worksheet that I released using
Marshal.ReleaseComObject(...). I want to iterate over a collection of
Excel.Worksheet and find out which is disposed.
Currently the workaround for me (bad one) is

try
{
string name = worksheet.Name;
}
catch(Exception e)
{
// this one was release as I cannot access it
worksheet = null;
}

Is there any other method through which I can check for a VALID(not
released) COM object?

Regards,
 
J

Jeroen Mostert

abhimanyu said:
I have a method Marshal.IsComObject(...) that returns TRUE if an
object is a COM object.
I have an object of Excel.Worksheet that I released using
Marshal.ReleaseComObject(...). I want to iterate over a collection of
Excel.Worksheet and find out which is disposed.

There's no way to determine whether an object is disposed other than using
it and getting an ObjectDisposedException. And that's actually the *good*
scenario. If you were working with pure COM, you'd have no way at all of
knowing whether an interface pointer was valid, and you'd likely just get a
crash if you use an invalid one.

You must keep track of when an object was disposed yourself. In general, do
not dispose objects until you're certain (or have made certain) that nobody
will use them anymore, then you can omit keeping track.
Currently the workaround for me (bad one) is

try
{
string name = worksheet.Name;
}
catch(Exception e)

Catch specific exception types, not Exception. The call to worksheet.Name
could fail for multiple reasons, not all of which should simply be silently
discarded.
{
// this one was release as I cannot access it
worksheet = null;
}

Is there any other method through which I can check for a VALID(not
released) COM object?
If you know you released the object, why do you need to check for it here?
Somewhere inbetween you discarded information or failed to propagate it.

Why don't you set the reference to null when you release it, rather than
when you find out it was released? If the worksheet is in a collection, why
don't you remove it from the collection?
 
A

abhimanyu

Actually, If I am keeping a collections of Sheets in a Dictionary<T>.
If I delete a Excel worksheet manually in Excel, the reference remains
in my Dictionary and when I try to use it, it throws and exception.

There may be other workaround to this problem by following a certain
pattern, But what I wanted to know was whether there is a method that
can avoid that throw.

Regards,
 
J

Jeroen Mostert

abhimanyu said:
Actually, If I am keeping a collections of Sheets in a Dictionary<T>.
If I delete a Excel worksheet manually in Excel, the reference remains
in my Dictionary and when I try to use it, it throws and exception.
I don't know the details of the Excel automation model, but I'd be surprised
if there was no way to detect that the sheet was deleted. There is probably
an event handler for that.
There may be other workaround to this problem by following a certain
pattern, But what I wanted to know was whether there is a method that
can avoid that throw.
To the best of my knowledge, there is not, and even relying on an exception
being generated here is iffy. Using an object when you're not sure if it's
still valid is a bad approach, because you're relying on the COM server to
detect the error for you.

A better way would be to *not* keep the collection of Sheets yourself, but
rely on Excel's collections instead, in combination with some unique sheet
identifier if necessary for maintaining your own data. Do not use a Sheet
without looking up if it still exists.
 

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