Intra-thread lock

C

cj_junktrap

Hi

Is there something like an intra-thread lock? I'm trying to prevent
re-entrant code, and the lock statement will only prevent one thread
from entering the critical section while another thread is in it -
since my code is triggered by a gui event, it's not impossible that it
could be called twice from the same thread. I could simulate a lock by
having a private variable "busy" and setting that to true when I start
processing, false when I stop, and check it before I begin processing -
but then either I have to throw an exception if I'm already busy
processing (which I'd prefer not to do), or I'd have to use a polling
wait loop to simulate a blocking call - which seems ugly.

Any ideas of a better way to do this?

Thanks
 
M

Markus Stoeger

Hi

Is there something like an intra-thread lock? I'm trying to prevent
re-entrant code, and the lock statement will only prevent one thread
from entering the critical section while another thread is in it -
since my code is triggered by a gui event, it's not impossible that it
could be called twice from the same thread. I could simulate a lock by
having a private variable "busy" and setting that to true when I start
processing, false when I stop, and check it before I begin processing -
but then either I have to throw an exception if I'm already busy
processing (which I'd prefer not to do), or I'd have to use a polling
wait loop to simulate a blocking call - which seems ugly.

Any ideas of a better way to do this?


I'm not 100% sure if I fully understand what you mean. While GUI event
is being processed, you can be sure that it will _not_ be fired a second
time because the windows message loop is blocked until your processing
is done (unless you are calling something like Application.DoEvents in
your processing code, which I hope you don't anyway ;-).

Anyway, you cannot have the current thread wait until the current thread
is done processing something else. That would always result in a dead lock.

The method with the "busy" variable would work. If busy is already true
-> handle it! Either by throwing an exception or by enqueuing the new
work item somewhere for later processing.

hth,
Max
 
C

Carl Daniel [VC++ MVP]

Hi

Is there something like an intra-thread lock? I'm trying to prevent
re-entrant code, and the lock statement will only prevent one thread
from entering the critical section while another thread is in it -
since my code is triggered by a gui event, it's not impossible that it
could be called twice from the same thread. I could simulate a lock
by having a private variable "busy" and setting that to true when I
start processing, false when I stop, and check it before I begin
processing - but then either I have to throw an exception if I'm
already busy processing (which I'd prefer not to do), or I'd have to
use a polling wait loop to simulate a blocking call - which seems
ugly.

Any ideas of a better way to do this?

Use ThreadPool.QueueUserworkItem to effect a queue of work. Depending on
the function, it may be appropriate to simply ignore attempts at re-entry -
only you can decide for sure.

-cd
 
D

Daniel MOSMONDOR - Mosh

i guess that second gui event can't come while first is processed due to
design of gui events that are in fact window messages.

other than that, use simple bool variable to cover possibility of
rentrancy - for example when you have form_onSize that you want to hande and
you have resizing the form from withing the event...

bool _inResize=true;

void form_onSize(EventArgs)
{
if (!_inResize) {
_inResize=true;
// do something
...
...
_inResize=false;
}
}
 
C

cj_junktrap

Markus said:
I'm not 100% sure if I fully understand what you mean. While GUI event
is being processed, you can be sure that it will _not_ be fired a second
time because the windows message loop is blocked until your processing
is done (unless you are calling something like Application.DoEvents in
your processing code, which I hope you don't anyway ;-).

Anyway, you cannot have the current thread wait until the current thread
is done processing something else. That would always result in a dead lock.

The method with the "busy" variable would work. If busy is already true
-> handle it! Either by throwing an exception or by enqueuing the new
work item somewhere for later processing.

hth,
Max

Well, I am using DoEvents, as I mentioned in the other thread, but even
without that it could still be called twice. Picture this: I have a
form, with two buttons. In my form constructor, or somewhere, I create
an instance of my object. Each button calls myObject.DoSomething(),
which, say, displays another form using form.Show(). When this other
form is closed, it raises an event or calls a delegate. Now the user
clicks on button 1, but doesn't close the form yet; then clicks on
button 2. My DoSomething() method will then be called again.

Basically, my problem is that I have an app with potentially many
forms; one of them will trigger the opening of a 2nd form. I want the
user to still be able to use the other forms, so I can't open this 2nd
form using ShowDialog, since it will be modal with respect to the
entire app. If I could make it modal only with respect to its parent
form, that would solve all my problems.
 
C

cj_junktrap

Daniel said:
i guess that second gui event can't come while first is processed due to
design of gui events that are in fact window messages.

other than that, use simple bool variable to cover possibility of
rentrancy - for example when you have form_onSize that you want to hande and
you have resizing the form from withing the event...

bool _inResize=true;

void form_onSize(EventArgs)
{
if (!_inResize) {
_inResize=true;
// do something
...
...
_inResize=false;
}
}

Yes, but then the second time it's called it will simply return without
doing anything, which isn't what I want. I want it to wait until the
busy flag is false, but without a polling loop.
 
L

Lloyd Dupont

Well, I am using DoEvents, as I mentioned in the other thread, but even
without that it could still be called twice. Picture this: I have a
form, with two buttons. In my form constructor, or somewhere, I create
an instance of my object. Each button calls myObject.DoSomething(),
which, say, displays another form using form.Show(). When this other
form is closed, it raises an event or calls a delegate. Now the user
clicks on button 1, but doesn't close the form yet; then clicks on
button 2. My DoSomething() method will then be called again.

Basically, my problem is that I have an app with potentially many
forms; one of them will trigger the opening of a 2nd form. I want the
user to still be able to use the other forms, so I can't open this 2nd
form using ShowDialog, since it will be modal with respect to the
entire app. If I could make it modal only with respect to its parent
form, that would solve all my problems.
Apart from the fact you are confused I hardly see any problem in what you
tryed to achieve.
Not being sure of what is your problem exactly I wrote a a possible (and
possibly irrelevant) solution below.

class AnObject : Object
{
bool done = false;
public void DoSomethingOnce()
{
if(done)
return;
DoItDamnIt();
done = false;
}
void DoItDamnIt()
{
// whatever it is you want to do
}
}
class MyForm : Form
{
AnObject anObj;
Button perhaps, maybe;

public MyForm(AbObject anObj)
{
this.anObj = anObj;

perhaps = new Button();
perhaps.Location = new Point(10, 10);
perhaps.Parent = this;
perhaps.Text = "Perhaps";
perhaps.Click += delegate(object sender, EventArgs e) { new
MyForm(anObj).Show(); };

maybe = new Button();
maybe.Location = new Point(80, 10);
maybe.Parent = this;
maybe.Text = "Maybe";
maybe.Click += delegate(object sender, EventArgs e) {
anObj.DoSomethingOnce(); };
}
}
 

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