Red Semaphore. Ideas?

  • Thread starter Thread starter tommaso.gastaldi
  • Start date Start date
T

tommaso.gastaldi

Sometimes I just want to avoid the User might click again on a button
(or other control) before the tasks attached to the click event are
over (to avoid that he may unwillingly re-run them).

So far, I have been using a kind of "Red Semaphore" (_SR) boolean flag
to do that, but actually I feel that my solution is quite awkward. Does
anybody has a more elegant way to propose?

-Tom
-------------

Private ButtonTestCondition_SR As Boolean

Private Sub ButtonTestCondition_Click(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
ButtonTestCondition.Click
If Me.ButtonTestCondition_SR Then Exit Sub
Me.ButtonTestCondition_SR = True

Me.ExecuteTask()

Me.ButtonTestCondition_SR = False
End Sub

----------------
 
AFAIK this is generally done by setting the Enabled property to false so
that the button is grayed.
 
How about greying out the button so he can't push it?

CType(sender, Button).Enabled = False
Me.ExecuteTask()
CType(sender, Button).Enabled = True
 
Hello tomasso,

The click event can only be reentered in two circumstances:
· If you use Application.DoEvents: I suggest you to set your Red Semaphore in the same procedure where you call DoEvents, or it may be difficult to trace reentrance (in large projects). It could be something like this:

Private Sub ButtonTestCondition_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonTestCondition.Click
Me.ExecuteTask()
End Sub

Private Sub ExecuteTask() 'May be called from different parts of the code.
Static SR As Boolean 'The runtime initializes it to False.
If SR Then Exit Sub
SR = True
'Long running code that calls DoEvents.
SR = False
End Sub

· If you use threads: The same apply, but now you should use a class level boolean (as in your example) and set it to false when the thread ends. How you do this depends on your threading design: Just before the thread ends, or in an event fired when the thread ends.

Anyway, if the process takes more than one second, you should give the user a clue that there is a pending job: Disable all controls that call ExecuteTask, show the WaitCursor or AppStarting cursor or show a progress indicator.
If ExecuteTask is recursive, the best approach is the example you gave.

Regards.


<[email protected]> escribió en el mensaje | Sometimes I just want to avoid the User might click again on a button
| (or other control) before the tasks attached to the click event are
| over (to avoid that he may unwillingly re-run them).
|
| So far, I have been using a kind of "Red Semaphore" (_SR) boolean flag
| to do that, but actually I feel that my solution is quite awkward. Does
| anybody has a more elegant way to propose?
|
| -Tom
| -------------
|
| Private ButtonTestCondition_SR As Boolean
|
| Private Sub ButtonTestCondition_Click(ByVal sender As
| System.Object, ByVal e As System.EventArgs) Handles
| ButtonTestCondition.Click
| If Me.ButtonTestCondition_SR Then Exit Sub
| Me.ButtonTestCondition_SR = True
|
| Me.ExecuteTask()
|
| Me.ButtonTestCondition_SR = False
| End Sub
|
| ----------------
 
Very nice and complete advice Jose. Thank you :)

What you say is almost always so, the only exception I can remember
seem be given by long running tasks launched by a NumericUpDown I
noticed that if you do not cut them ar the very source (valuechanged
handler), the calls seem to accumulate and fire anyway later (no way to
filter them with a semaphore on the called routine) ...

-tom

José Manuel Agüero ha scritto:
 
Back
Top