49

I have some COM component which I call from some c# dll.

I also have a winforms app that uses that .dll.

When I close the app I get this exception:

COM object that has been separated from its underlying RCW cannot be used.

The stack trace shows this exception comes from a destructor in the .dll. I implemented this destructor to call some cleanup method in the COM.

Why does this happen? How is it best to solve it?

Iain Holder
  • 14,172
  • 10
  • 66
  • 86
Yaron Naveh
  • 23,560
  • 32
  • 103
  • 158
  • 5
    Read this: http://jake.ginnivan.net/vsto-com-interop – Jeremy Thompson May 01 '13 at 02:23
  • Possible duplicate of [COM object that has been separated from its underlying RCW cannot be used](http://stackoverflow.com/questions/1567017/com-object-that-has-been-separated-from-its-underlying-rcw-cannot-be-used) – bluish Oct 15 '15 at 09:22

1 Answers1

34

The issue is described here:

Is it safe to call an RCW from a finalizer?

and here:

Release Excel Object In My Destructor

The trouble is that not only is the timing as to when these objects are to be garbage collected uncertain, but the order in which the finalizers are called is also nondeterministic. In this case, a Runtime Callable Wrapper also has a finalizer, which calls Marshal.FinalReleaseComObject on itself, which has the result of decrementing the reference count on the COM side of the fence so that this COM object can be released. But since the order in which the finalizers are called is uncertain, it is very possible that the finalizers for the COM objects that your object references will fire before the finalizer for your object. So the code within your finalizer could work sometimes, but, most of the time, one or more of the Runtime Callable Wrappers that your object references will have already had their finalizers called and the underlying COM object will have been released before your finalizer gets to execute its code.

Community
  • 1
  • 1
Ran
  • 534
  • 6
  • 12
  • 82
    I did not follow a thing! :x – nawfal Feb 22 '12 at 08:35
  • 12
    It's pretty clear: the COM wrapper around the object you instantiated might be cleaned up before you get around to cleaning it up yourself. Translation: If your Dispose() attempts to call Marshal.ReleaseCOMObject(x) when that underlying x has already gone out of scope, your Dispose() will fail. Gotta check that scope/lifecycle. Thanks for the good links, @Ran. – JMD Aug 28 '14 at 17:31