Thought: Wow, haven’t posted much in the software blog recently – been
so busy writing software that I haven’t had time to talk about it.
This week I found out about thread marshalling. Simply put, it involves
marshalling of execution through win-form controls from worker threads.
Justin Rogers writes and excellent article about it here, so I’ll not
go too far into the gory details (or not so gory as it appears).
I wrote a cool thread manager component that maintains a queue of jobs.
The thread manager permits the execution of a finite number of
worker threads, one per job up to a maximum limit. Once the maximum number of
threads are allocated, and busy, the thread manager will queue up
subsequent jobs until a worker thread becomes free to process the job.
My thread manager component works well, so I built a print manager on
top of it. The print manager manages print jobs (as the name suggests)
and monitors the print spooler for the health of print jobs. When a
print job starts, completes, or is aborted the print manager will fire
I was talking with a colleague about this the other day and he
mentioned that I need to be careful when calling win-form controls from
my print manager event handlers, since they run on a different
thread to the win-form application. So I looked into this problem a
Windows maintains a message pump for each windowed
application and pushes messages onto the pump when an event occurs.
This ensures that multiple window events, such as a mouse click or a
keyboard press, do not conflict and the event handlers execute
sequentially. This is all fine and dandy until a worker thread fires an
event, which, when trapped by an event handler, requires some
feedback sent to the user. Fortunately the .NET framework provides a nice
Each event handler that responds to events fired by a worker thread
should check to see if the calling thread is the same as that of the
host win-form application (UI thread). The Control class has a method
called InvokeRequired, which will return true if the the current thread
is not the UI thread. Once it’s established that the threads are
different, a call to Control.Invoke will ensure that changes to a
win-form control are made on the UI thread.