We interupt this blog’s coverage of OOPSLA with a quick observation & question related to development…
I’m hacking around writing a Word 2003 SmartTag in C# (more on the why later). I wanted my recognizer to be document-dependent – i.e. depending on some custom document properties, I wanted to change what gets recognized. A little digging reveils that there is no way (that I could find) to access the Word object model from the recognizer! The Recognize (and Recognize2) method receives strings as parameters, but it doesn’t receive an app-specific target object. This is unlike the Smart Tag Action‘s InvokeVerb (and InvokeVerb2) method which receives a Range object (from which you can navigate to the containing document, application and window) when running inside of Word. Bummer.
I think the reason for this is that the recognizer appears to run on a background thread while the action appears to run on the main app thread. Furthermore, both threads are STA apartment threaded, so if I can access the COM-based object model from the action thread, I can’t access it directly from the recognizer thread. I actually hacked up an add-in to provide the ActiveDocument to the recognizer thru a backchannel and it hangs Word on shutdown. I thought there might be an issue releasing the COM reference, but explicitly releasing it crashes the recognizer the next time it accesses the ActiveDocument.
So I’ve come to the conclusion that I somehow need to marshal this call from the background thread to the main app thread the action and addin are runing on (I did verify that both of those run on the same thread). The question is, what’s the best way to do that given that I’m writing this in C#? I thought I might use a system similar to Windows Form’s Control.Invoke(…), but it turns out that works by sending windows messages which isn’t particularly feasible for my problem. So now I’m thinking I have pass the ActiveDocument reference to the background thread using CoMarshalInterface. Or I might be able to use RemotingServices.Marshal() instead.
Anyone have any ideas? If so, leave a comment or drop me a line.