winform synchronization 'onPaint', 'onKeyUp', and 'lock'

F

fei.liu

Hello, in the application I am developing, I am having trouble to
synchronize event triggered actions using 'lock(ob){...};' technique.
Here is a outline of my code:

class C{
int x = 0;
public void incre(){ if(x < 20) x++; }
}

class Form1: WinForm{

...//all the usual initialization setup code.
C c;
Object ob = new Object();
public void onPaint(..., ...) // event handler of a paint event
{
lock(ob){
c.incre();
}
}
pubilc void onKeyUp(..., ...) // event handler of a keyboard event
{
if(e.Key == Keys.G) // increase C.x when user presses 'g'
{
lock(ob){
c.incre();
}
}
}
}

Now, theoretically, because c.incre() call is protected by lock
synchronization, c.x should always <= 20; But to my surprise, this code
produces different result, c.x = 20 randomly. It seems my lock
synchronization did not work and two threads (paint thread, keyboard
handler thread) can execute c.x simultaneously...

If you know what I did wrong here, please advise. Thanks,
 
G

Guest

But does it ever reach 21, the if will increment x for all values below 20
i.e. 0 to 19, when 19 is incremented it becomes 20, the test will then fail
and x should remain 20.
 
M

Mehdi

class C{
int x = 0;
public void incre(){ if(x < 20) x++; }
} [...]
Now, theoretically, because c.incre() call is protected by lock
synchronization, c.x should always <= 20; But to my surprise, this code
produces different result, c.x = 20 randomly. It seems my lock
synchronization did not work and two threads (paint thread, keyboard
handler thread) can execute c.x simultaneously...

If you know what I did wrong here, please advise. Thanks,

There is no "paint thread" or "keyboard thread". Under Windows, all the
events raised by UI controls are executed in the UI thread (actually, the
OnXXX methods are not events but you get my point). So in your exemple, you
only have one thread in action, the UI thread, which means that you do not
need to synchronize access to your object c. As for the results you're
getting, they seem perfectly normal to me. c.x starts at 0 then increases 1
by 1 at every paint event and whenever the user presses the g key until it
reaches 20 at which point it remains there. What do you think is wrong with
that?
 
F

fei.liu

Mehdi said:
class C{
int x = 0;
public void incre(){ if(x < 20) x++; }
} [...]
Now, theoretically, because c.incre() call is protected by lock
synchronization, c.x should always <= 20; But to my surprise, this code
produces different result, c.x = 20 randomly. It seems my lock
synchronization did not work and two threads (paint thread, keyboard
handler thread) can execute c.x simultaneously...

If you know what I did wrong here, please advise. Thanks,

There is no "paint thread" or "keyboard thread". Under Windows, all the
events raised by UI controls are executed in the UI thread (actually, the
OnXXX methods are not events but you get my point). So in your exemple, you
only have one thread in action, the UI thread, which means that you do not
need to synchronize access to your object c. As for the results you're
getting, they seem perfectly normal to me. c.x starts at 0 then increases 1
by 1 at every paint event and whenever the user presses the g key until it
reaches 20 at which point it remains there. What do you think is wrong with
that?

Thank you, actually c.x gets over 21 sometimes (my code is logically
more complicated) so it may be due to other bug but not
synchronization. Thanks for the clarification on the thread model.
However, when in a debugger, I see 3 threads when I run winForm app,
one is GC thread, one is main thread, I do't know what's the 3rd one?
Is it UI thread? THen what's a main thread? Thanks,

Fei
 
B

Brian Gideon

Thank you, actually c.x gets over 21 sometimes (my code is logically
more complicated) so it may be due to other bug but not
synchronization. Thanks for the clarification on the thread model.
However, when in a debugger, I see 3 threads when I run winForm app,
one is GC thread, one is main thread, I do't know what's the 3rd one?
Is it UI thread? THen what's a main thread? Thanks,

Fei

Just going on memory alone (sometimes that's dangerous) I belive there
are two threads related to the GC. The 3rd may be the finalizer
thread. In the case of a windows forms application the main thread is
the same as the UI thread. The UI message pump gets started via
Application.Run in the Main method.

Brian
 
F

fei.liu

Brian said:
Just going on memory alone (sometimes that's dangerous) I belive there
are two threads related to the GC. The 3rd may be the finalizer
thread. In the case of a windows forms application the main thread is
the same as the UI thread. The UI message pump gets started via
Application.Run in the Main method.

Brian

Thank you all for the thoughtful input.
 

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