Re: Threads, MTA and COM objects

Tech-Archive recommends: Fix windows errors by optimizing your registry



On Sun, 18 Jan 2009 11:06:44 -0800, Steve K <nospam@xxxxxxxxxxxx> wrote:

[...]
I definitely wouldn't bother implementing a SynchronizationContext sub-class. Just seems like too much effort for something that could easily be handled via a simple synchronized queue of delegates (with the main thread being the consumer of the queue).

The one example (which is very close to what I'm after) that I cam across did something very similar to this. Overall it seems like way too much work for what I need to accomplish, but then again considering how little I know about COM and threading (beyond the very basics) baybe this IS what it takes.

I'm not sure what the intended antecedent for your pronoun "this" is. Are you referring to sub-classing SynchronizationContext? Or the simpler technique of just creating a queue of delegates that's consumed on an appropriate STA thread?

[...]
I don't want to lean on the Form and it's STA context to solve the COM issue. I have found a couple examples that use this approach and I'm not sure that I will always have Forms in this application and as such I don't want to rely on them.

I still don't know enough about your overall design to give specific advice. However, if the GUI is secondary to the program, _and_ you have a reliable way of processing the messaging on your main thread, it seems to me that the simplest approach would be to run the GUI on a dedicated second thread that you've set to be STA (required for Forms namespace stuff), and then let all of the COM object stuff happen on the main thread.

Two other approaches that come to mind:

-- As I mentioned, create a second thread that you set to STA and use to consume delegates from a queue where the delegates are produced by arbitrary other threads, for the purpose of executing the COM features, or...

-- Create a second thread that you set to STA and use to consume the actual commands that represent the work you want the COM object to do. The only real difference between this and the previous suggestion is what gets put into the queue. Either way, you have to pass some kind of data to the STA thread so that it can do the actual work. I think the delegate approach is more general and so could be more reusable, but if you're already dealing with some kind of message-passing between threads anyway, it's possible this approach would involve less effort given your current code base.

So, that's three different ideas, any of which would probably work fine. You've already identified the main problem: you need to execute your COM functions on an STA thread. So the only question that remains is how you would like to get the command to execute those functions to an appropriate STA thread. Since you've stated you'd like to avoid a dependency on the GUI objects for that purpose, you'll have to implement your own cross-thread data passing somehow. The exact mechanism to use probably doesn't really matter much, since in the end none of the alternatives are too terribly involved (you could write a delegate queue solution in probably 30 lines of code or so, and I'd guess the other alternatives would be similarly simple).

Pete
.



Relevant Pages

  • Re: Threads, MTA and COM objects
    ... Just seems like too much effort for something that could easily be handled via a simple synchronized queue of delegates (with the main thread being the consumer of the queue). ... You could still use the ThreadPool for the COM object itself if you want, but you'd use the STA thread to execute code that requires STA by producing delegates for the STA thread to consume. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Interfaces and Events
    ... you have the queue as the focus point. ... William Stacey [MVP] ... Instead of using delegates and events, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Start more than one async methods but wait previous to finish before start next
    ... I want to know how to start two or more async methods, ... I do not think that DoEvents() is the best solution (as a matter of fact you ... You could create a Queue of delegates and a method that reads from that ... queue and invoke the delegate. ...
    (microsoft.public.dotnet.languages.csharp)