This is a multi-part message in MIME format.
------=_NextPart_000_0009_01C5B066.058A4E30
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
We have an application written in c# that uses pinvoke to call =
SendMessage to send messages between threads. We also use Monitor class =
(via the c# lock keyword) for thread synchronization.=20
I have discovered the following behaviour, which surprised me:
0) Thread1 (T1) creates a NativeWindow, to be used as a SendMessage =
target, then calls Application.Run()
1) T1 enters an event handler
2) inside the event handler, T1 enters a lock region (calls =
Monitor.Enter), but blocks because another thread (call it T2) has =
entered
3) T3 calls SendMessage on the NativeWindow created by T1
4) The message handler for the message sent in 3) is run, while T1 is in =
the Monitor.Enter() call.
If I do the following experiment, I get different behaviour (code =
changes in bold)
0) Thread1 (T1) creates a System.Windows.Forms.Control, to be used as an =
Invoke target, then calls Application.Run()
1) T1 enters an event handler
2) inside the event handler, T1 enters a lock region (calls =
Monitor.Enter), but blocks because another thread (call it T2) has =
entered
3) T3 calls Invoke on the Control created by T1
4) T1 Monitor.Enter() returns (T2 called Monitor.Exit), and ultimately =
the event handler T1 is running returns
5) The delegate passed into Control.Invoke() in step 3) runs
The behaviour in the 2nd experiment is what I was expecting in the first =
experiments' case. It appears, in the first experiments case, that =
inside Monitor.Enter(), messages sent by SendMessage are being =
dispatched before it returns.
Does anyone have any idea what I can do, in the SendMessage case, to get =
the behaviour I am seeing using Control.Invoke()? I would rather not use =
Control.Invoke() because it has a couple limitations relative to using =
SendMessage() (but I may have to...)
Thanks for any insights any of you might have.
Craig Bryant
Senior Software Engineer
Tektronix, Inc
Beaverton, OR
------=_NextPart_000_0009_01C5B066.058A4E30
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2900.2627" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY>
<DIV><FONT face=3DArial size=3D2>We have an application written in c# =
that uses=20
pinvoke to call SendMessage to send messages between threads. We also =
use=20
Monitor class (via the c# lock keyword) for thread=20
synchronization. </FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I have discovered the following =
behaviour, which=20
surprised me:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>0) Thread1 (T1) creates a NativeWindow, =
to be used=20
as a SendMessage target, then calls Application.Run()</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>1) T1 enters an event =
handler</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>2) inside the event handler, T1 enters =
a lock=20
region (calls Monitor.Enter), but blocks because another thread =
(call it=20
T2) has entered</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>3) T3 calls SendMessage on the =
NativeWindow=20
created by T1</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>4) The message handler for the message =
sent in 3)=20
is run, <EM>while T1 is in the Monitor.Enter() call</EM>.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>If I do the following experiment, I get =
different=20
behaviour (code changes in bold)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>0) Thread1 (T1) creates a=20
<STRONG>System.Windows.Forms.Control</STRONG>, to be used as an Invoke =
target,=20
then calls Application.Run()</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>1) T1 enters an event =
handler</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>2) inside the event handler, T1 enters =
a lock=20
region (calls Monitor.Enter), but blocks because another thread =
(call it=20
T2) has entered</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>3) T3 calls <STRONG>Invoke on the =
Control</STRONG>=20
created by T1</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>4) T1 Monitor.Enter() returns (T2 =
called=20
Monitor.Exit), and ultimately the event handler T1 is running=20
returns</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>5) The delegate passed into =
Control.Invoke() in=20
step 3) runs</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>The behaviour in the 2nd experiment is =
what I was=20
expecting in the first experiments' case. It appears, in the first =
experiments=20
case, that inside Monitor.Enter(), messages sent by SendMessage are =
being=20
dispatched before it returns.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Does anyone have any idea what I can =
do, in the=20
SendMessage case, to get the behaviour I am seeing using =
Control.Invoke()? I=20
would rather not use Control.Invoke() because it has a couple =
limitations=20
relative to using SendMessage() (but I may have to...)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Thanks for any insights any of you =
might=20
have.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Craig Bryant</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>Senior Software Engineer</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>Tektronix, Inc</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>Beaverton, =
OR</FONT></DIV></BODY></HTML>
------=_NextPart_000_0009_01C5B066.058A4E30--