invoking on UI thread

  • Thread starter Thread starter Paul
  • Start date Start date
P

Paul

I understand the notion that a UI thread should be
responsible for managing the UI elements; therefore,
worker threads need to call invoke on a control. I don't
understand the technical reason for this. What is it
about the Win32 message loop that doesn't like worker
threads to update the UI and why does it work anyway (at
least most of the time)?

Thanks for shedding some light,
Paul
 
Hi Paul,
WinfowsForms is build over the Windows GUI. Most (if not all) of the visual
properties of the controls are manipulated via SendMessage calls.
SendMessage works differently if it is called from the thread created and
owning the window handle and when it is called across thread boundaries. In
the first case the winproc is called as any other routine. In the second
case, though, thread context has to be switched. This is done by posting the
message in the UI (thread that owns the target window handle) thread's
message queue and blocking the caller unitl the message gets processed (this
is how Win32 SendMessage works). In other words targeted UI thread has to
have running message loop in order to process a *sended* message. This is
deadlock prone because all this acts behind the scene. For example if the UI
thread stays blocked awaiting the worker thread to finish - this is 100%
deadlock. Furthermore frameworks keep information in the thread stack
(therad that ctreates the control), which makes this information invalid
when it is used from code executed in other thread context.
Anyway I haven't seen so far framework for Win where UI can be updated from
thread different from the one created the win control. The frameworks I have
experience with are: MFC, VCL, OWL2 and WidowsForms. All they have this
limitation. Even AFAIK some frameworks are designed to prevent this because
is deadlock prone.

HTH
B\rgds
100
 
Thanks HTH for the info. I'm curious as to why it
sometimes works for a worker thread to update a UI
control. For instance, it could update a textbox.
Perhaps the textbox isn't a native control? Additionally,
the UI control is just another object. I suppose I'm
still hazy why two threads can't access the same control
if you can avoid race condition. Also, if a worker thread
calls Invoke() on a control, is it merely marshalling the
call's parameters and proceed with the rest of its task or
is it waiting for the control to finish its task,
therefore opening a possibility for a deadlock?

Paul
 
"I'm curious as to why it
sometimes works for a worker thread to update a UI
control. For instance, it could update a textbox.

Frankly, I don't know. And I don't think someone from MS will bother itself
to explain us why is this. I'm curious too. Unfortunately both ROTOR and
MONO projects, which sources we can look at don't implement WindowsForms
classes.
Perhaps the textbox isn't a native control?

It has a native controls underneath.
Additionally, the UI control is just another object. I suppose I'm
still hazy why two threads can't access the same control
if you can avoid race condition.

Actually, it serve more as a *wrapping* objects for a native windows
control. Some of the properties and methods are translated to SendMessage
calls.
I think you can use any method or property that doesn't involve the native
control from any thread and it will work as long as you make sure the usage
is thread safe.
For example MFC keeps table to map between windows handles (HWND) and
MFC-window classes. That table is kept in the thread stack and that is why
methods that need HWND cannot be called from within different thread. I have
read that one of the reason for doing that is to prevent using window
classes from another threads. Again, unless we have the source codes nobody
will tell us why it is like that in WindowsForms.

Also, if a worker thread
calls Invoke() on a control, is it merely marshalling the
call's parameters and proceed with the rest of its task or
is it waiting for the control to finish its task,
therefore opening a possibility for a deadlock?

It will definitely wait for the control to finish its task if the call is
made form another thread. Otherwise thread context switching cannot be done.

B\rgds
100
 
Back
Top