tags:

views:

44

answers:

1

I'm trying to implement a singleton class, that holds a com object inside it. Class implements IDisposable interface, but when I try to implement a finalization method, I get an exception of access to com object from another thread.

This happens because clr uses a different thread when finalizes objects.

Is there any way to implement such a thing or maybe I just doing something wrong?

+3  A: 

You only need to implement a finalizer if the class diectly manages the non-managed resource. A COM object is wrapped in a RCW (runtime callable wrapper), so there is already a managed type between your type and the COM interface pointer.

Richard
@Richard - You said that you only need to implement a finalizer if your class directly manages the non-managed resource. You should also implement a finalizer if your class holds any object that implements IDisposable.
dewald
hmlet's go with examplesI'm using Office.Interop to access Word's spellchecking capabilities when I'm done, I need Word background app to be closed, so I implemented class, that holds WordApplication instance and want it to call closing method on disposing or finalizing, and the problem not really in resources but in calling closing method of word application instance
Neverrav
@dewald: incorrect. In that case implement IDisposable to allow callers to cleanup without waiting on GC. But you *don't* need a finalizer: the GC will finalise the referenced native resource wrapper for you (this is a corollary of the rule that in a finalizer you cannot use referenced managed objects because the GC may already have destroyed them).
Richard
@Neverrav: When the GC finalizes the RCW from the Office PIA and releases the last reference to the Application object then the Office app should shut down. Or you explicitly release using `Marshall` helpers in a `Dispose` implementation. In practice Office apps don't always go away when they should (I've hit this in pure COM cases, this is a problem with Office automation).
Richard
@Richard: I concede, you are correct. I was mis-remembering the dispose pattern. I incorrectly thought that every time you implement IDisposable, you also *should* override the Finalize method. I re-read the "Implementing a Dispose Method" on MSDN and it says that you should only override Finalize if you directly manage a non-managed resource, not indirectly via a managed reference.
dewald