How to run code on the main thread?

O

Olivier

Hello,

We have to integrate with an application A. This application is written
using unmanaged C++ (I guess) but has a .NET API. The first problem is that
this API is not accessible from an external application (it it just for
internal use)

So, I have created a .NET Assembly (C#) which is loaded during the startup
of the application A. In this assembly I register a .NET class for COM
We have another application B that will create an instance of this .NET/COM
class to do its work.

Now the problem: In the implementation of this .NET/COM class I have to
execute some code but this must be done on the main thread of the
application A (otherwise some strange things or crash happen)

How can I do that?

Thanks in advance

Olivier.
 
Z

ZestTOon

Peter Duniho said:
[...]
Now the problem: In the implementation of this .NET/COM class I have to
execute some code but this must be done on the main thread of the
application A (otherwise some strange things or crash happen)

How can I do that?

Hard to say without more information. It's possible you can take
advantage of the main thread being a COM STA thread, and use the COM
message pumping to execute code there (but it will only happen if that
main thread winds up waiting for something). If the main thread is a .NET
Forms or WPF thread, you can invoke/dispatch method calls to it using a
SynchronizationContext, _if_ the thread has a message pump running.

If "application A" isn't designed for this use case, you may in fact be
out of luck, especially if neither of the above apply. Of course, if you
can modify "application A", you can add functionality to it so that it
either calls a special method in your library specifically for the purpose
of executing it on the main thread, or even providing a more
general-purpose delegate-invocation queue for that purpose.

It depends a lot on what exactly "application A" is doing, and without
those details, it's practically impossible to say for sure what might work
in your case.

Pete

Hello Pete,

First, thank you for your comments.

In fact, I have very little knowledge of the Application A internals, and I
can't change anything in this application by myself.

I'm sure that the main thread is not a .NET one because this application was
not developped using .NET. I just know that the .NET API I mentionned
earlier was added later, over the "legacy" code

One thing I didn't mentionned previously that may help finding a solution:

At startup, my assembly code is called in the context of the main thread of
the application A. So, is it possible to "save" this context somewhere in my
assembly and reuse it later in my .NET/COM class to execute my code in this
context.

I saw Thread.Context.DoCallback() in the .NET API. Can I use something like
this? (I'm not sure to understand the usage of this)

Best regards,

Olivier.
 
B

Ben Voigt [C++ MVP]

One thing I didn't mentionned previously that may help finding a
solution:
At startup, my assembly code is called in the context of the main
thread of the application A. So, is it possible to "save" this
context somewhere in my assembly and reuse it later in my .NET/COM
class to execute my code in this context.

If nothing else works, and this main thread is a GUI thread pumping at least
windows messages, then you can create a window. Anytime a message is sent
to that window later, your WndProc will be executed on the main thread
(DispatchMessage, which is called inside the native app's message loop, will
call your WndProc). But for obvious reasons this only works on a GUI thread
where DispatchMessage is called (pretty much all native GUI code calls
DispatchMessage).

In fact, if you make a .NET control (make sure the handle gets created
during your startup routine so it's bound to that thread) then .NET will do
exactly what I just described, and you should even be able to use
Control.Invoke (or Control.BeginInvoke) to execute code back on that thread
in the future.
 
R

Richard Guidry

Application.Current.Dispatcher.Invoke(delegate, params)
Hello,

We have to integrate with an application A. This application is written
using unmanaged C++ (I guess) but has a .NET API. The first problem is that
this API is not accessible from an external application (it it just for
internal use)

So, I have created a .NET Assembly (C#) which is loaded during the startup
of the application A. In this assembly I register a .NET class for COM
We have another application B that will create an instance of this .NET/COM
class to do its work.

Now the problem: In the implementation of this .NET/COM class I have to
execute some code but this must be done on the main thread of the
application A (otherwise some strange things or crash happen)

How can I do that?

Thanks in advance

Olivier.
On Tuesday, March 17, 2009 3:16 PM Peter Duniho wrote:


Hard to say without more information. It's possible you can take
advantage of the main thread being a COM STA thread, and use the COM
message pumping to execute code there (but it will only happen if that
main thread winds up waiting for something). If the main thread is a .NET
Forms or WPF thread, you can invoke/dispatch method calls to it using a
SynchronizationContext, _if_ the thread has a message pump running.

If "application A" isn't designed for this use case, you may in fact be
out of luck, especially if neither of the above apply. Of course, if you
can modify "application A", you can add functionality to it so that it
either calls a special method in your library specifically for the purpose
of executing it on the main thread, or even providing a more
general-purpose delegate-invocation queue for that purpose.

It depends a lot on what exactly "application A" is doing, and without
those details, it's practically impossible to say for sure what might work
in your case.

Pete
On Thursday, March 19, 2009 6:03 PM Ben Voigt [C++ MVP] wrote:
If nothing else works, and this main thread is a GUI thread pumping at least
windows messages, then you can create a window. Anytime a message is sent
to that window later, your WndProc will be executed on the main thread
(DispatchMessage, which is called inside the native app's message loop, will
call your WndProc). But for obvious reasons this only works on a GUI thread
where DispatchMessage is called (pretty much all native GUI code calls
DispatchMessage).

In fact, if you make a .NET control (make sure the handle gets created
during your startup routine so it's bound to that thread) then .NET will do
exactly what I just described, and you should even be able to use
Control.Invoke (or Control.BeginInvoke) to execute code back on that thread
in the future.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top