Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marshall to a thread manually

In WinForms, you have Control.BeginInvoke(), which means you can marshall a call from a background thread to the main UI thread that created the control's handle.

This is fine, but how (in C#) would you do this between two "standard" threads?

I have written a service bus, which has a processor thread to consume messages. I want a timer to fire, that causes that processor thread to do something, rather than the code running in the timer's thread.

Of course I can use thread syncronisation (Monitor/using() {...}) but wondered how it was done normally.

like image 903
Neil Barnwell Avatar asked Jun 24 '09 13:06

Neil Barnwell


2 Answers

Unfortunately the answer is hard to give here because it's highly dependent upon the nature of the thread.

Marshaling between threads isn't magic. There is an underlying mechanism which makes it possible to do. For example in WinForms, the Control.Invoke style functions work via message passing. There is a message posted to the UI thread, the message pump will eventually pump this message and convert it to a Marshal'd call.

In order to marshal a call between a standard thread, it must have some capability by which it can detect a marshal call wants to happen and then make that call happen. This is typically done by message passing of some sort.

IMHO, the most standard way of doing this is by having your thread implement, provide and install a SynchronizationContext. This is a more standard way of defining a Marshaling mechanism between threads.

like image 169
JaredPar Avatar answered Nov 18 '22 19:11

JaredPar


Windows Forms runs a message loop, which is why you can marshall to the UI thread for all sorts of tasks - it repeatedly looks for messages in its queue, which can be sent across thread boundaries.

If you want to do it manually, either create your own message loop (for one or more threads) or much simpler, use synchronisation primitives. AutoResetEvent would seem to be an appropiate one for this situation. You just need to call the Set and WaitOne methods at the right points, really (and be aware of deadlocks of course).

like image 29
Noldorin Avatar answered Nov 18 '22 19:11

Noldorin