Home All Groups Group Topic Archive Search About

Red Semaphore. Ideas?

Author
26 Apr 2006 2:04 PM
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

----------------

Author
26 Apr 2006 2:20 PM
Patrice
AFAIK this is generally done by setting the Enabled property to false so
that the button is grayed.

--
Patrice

<tommaso.gasta***@uniroma1.it> a écrit dans le message de news:
1146060262.225987.50***@i40g2000cwc.googlegroups.com...
Show quoteHide quote
> 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
>
> ----------------
>
Author
26 Apr 2006 2:32 PM
AMercer
How about greying out the button so he can't push it?

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

Show quoteHide quote
> 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
Author
26 Apr 2006 5:37 PM
tommaso.gastaldi
Thank you for your suggestions :)

-tom
Author
26 Apr 2006 6:38 PM
José_Manuel_Agüero
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.


Show quoteHide quote
<tommaso.gasta***@uniroma1.it> escribió en el mensaje news:1146060262.225987.50030@i40g2000cwc.googlegroups.com...
| 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
|
| ----------------
Author
26 Apr 2006 7:10 PM
tommaso.gastaldi
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:

Show quoteHide quote
> 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.
>
>
> <tommaso.gasta***@uniroma1.it> escribió en el mensaje news:1146060262.225987.50030@i40g2000cwc.googlegroups.com...
> | 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
> |
> | ----------------