From time to time Eric Carter shares with me some issues customers run into and wonders whether we can do something about it. The one I am going to talk about is quite interesting issue on its own AND I will talk about a solution we propose to this problem in my PDC session. So, if you like this stuff you should enjoy my PDC session as well.
So, here is the slightly edited thread.
From: Eric Carter To: Misha Shneerson
I’m out in North Carolina with support [engineers – M.S.] and they showed me this issue—incredible. Build a managed add-in for Excel and sync application events. Now try to embed any excel workbook into Word. Result—Word crashes.
From: Misha Shneerson To: Eric Carter
I did not know about this particular issue but , yep, I am very well aware that the way events are implemented in PIAs is problematic. The main problem is caused by the fact that there is side-effect to using PIAs eventing support which I call “ghost RCWs” - users do not see those RCW in their code but they are still created behind the scenes. To clarify what I mean - suppose Excel.Application exposes WorkbookOpen(Worbook) and WorkbookClose(Workbook) events (I am intentionally simplifying it here to only 2 imaginary evens off Excel’s Application). In my add-in code I only define an event handler for WorkbookOpen and in the handler itself I will call Marshal.RCO on the object to make sure there is no RCW hanging around. Sounds like I should not have outstanding RCWs wrapping the Workbook objects, right? Surprisingly, an RCW for the Workbook object will be re-created for me when WorkbookClose is fired even though I am not handling this event! What happens behind the scenes is that PIA’s eventing support creates an event sink which handles both WorkbookOpen and WorkbookClose but only WorkbookOpen calls the user’s delegate method. It only seems that WorkbookClose does nothing – but there is a side effect from the fact that this stub is defined at all – CLR still needs to marshal the parameters and that is how “ghost” RCWs are created.
Notice, that defining event handlers for both WorkbookOpen and WorkbookClose is not going to help the situation either because PIAs eventing support will create a separate sink object to handle WorkbookOpen (with side effect of marshalling COM object to RCW when WorkbookClose is called) and another sink object for WorkbookClose (with side effect of marshalling COM object to RCW when WorkbookOpen is called) .
For the rest of the thread I am describing how we are going to fix this. Fixing events for COM objects is relatively just a small part of the improvement CLR and Visual Studio are making to managed type system and COM interop. So, come and learn the bigger picture.