Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Button1.Enabled = False DOES NOT mean Button1 is disabled 1

Status
Not open for further replies.

earthandfire

Programmer
Mar 14, 2005
2,924
GB
There seems to be a lot of emotion regarding whether or not it is valid to use Application.DoEvents

The following code block is a time consuming process:

Code:
  Private Sub ProcessTakingALongTime()

    For a As Integer = 1 To 10
      For b As Integer = 1 To 100000000
        'do something really important here
      Next
      'simulate a progress bar
      Label2.Text = a.ToString
      Label2.Refresh()
    Next

  End Sub


To run this:

Code:
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Button1.Enabled = False
    ProcessTakingALongTime()
    Button1.Enabled = True

  End Sub

Two things:
(1) The program is unresponsive
(2) If the user clicks on the disabled button the code will run again (once for each click) despite it supposedly being disabled.

If ProcessTakingALongTime is spun off onto a separate thread, the program will become responsive, however the code will repeatedly run (once for each click).

Judicious use of Application.DoEvents solves both problems:

Code:
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Button1.Enabled = False
    ProcessTakingALongTime()
    Button1.Enabled = True
    Application.DoEvents()

  End Sub

gives an unresponsive program (unless multi-threaded) but processes the message queue before re-enabling the button.

Code:
  Private Sub ProcessTakingALongTime()

    For a As Integer = 1 To 10
      For b As Integer = 1 To 100000000
        'do something really important here
      Next
      'simulate a progress bar
      Label2.Text = a.ToString
      Label2.Refresh()
      Application.DoEvents()
    Next

  End Sub

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Button1.Enabled = False
    ProcessTakingALongTime()
    Button1.Enabled = True

  End Sub

gives a responsive program, if the user does happen to click on the disabled button, nothing will happen.

I would be interested to know what those who advocate not using Application.DoEvents would do in this situation.

By the way, this phenomenon or feature was discussed in detail in thread102-1068694
 
Rick, before posting I'd done some experiments with threading as well and each test "successfully" allowed the click to work on the disabled button. This was the main reason that I posted, to try to see if there was a "valid" alternative that actually worked. The code sample I presented was simplified.

First the bad news - your code wont compile.

Second change Protected del As ProcessDelegate to Dim del As ProcessDelegate and not only does it compile - it works. Well done.

Threading was what I thought to be the answer but probably as my threading tests were more simplistic than yours they didn't disable the button.

Now I've lost Modules and Application.DoEvents - Globals anyone?? [smile]
 
I was going to give you a star, Rick, but since your solution didn't compile, I'm not so sure.

Still, a minor change and it was the answer I was looking for - a way to avoid Application.DoEvents so ...
 
That code was cut/paste and modified with out an IDE or compile, if it only had one declaration error, I'd consider that a succuss ;)

You might want to move the delegate declaration out side of the sub though, I think that's why I had it declared as protected instead of dim.

-Rick

VB.Net Forum forum796 forum855 ASP.NET Forum
[monkey]I believe in killer coding ninja monkeys.[monkey]
 
Rick, I was only joking. [wink] Your solution was excellent, I'm only annoyed that I had played with threads and not found the correct route.
 
I should really add another threading FAQ that goes into delegates and early abortion. One of the things that turned me off about threading when I first got into it was the delayed exit method in all the samples.

-Rick

VB.Net Forum forum796 forum855 ASP.NET Forum
[monkey]I believe in killer coding ninja monkeys.[monkey]
 
I think its a fascinating and overwhelming topic - very powerful and very useful, but very dangerous in the wrong hands. If you could put something together that distills the pertinent points clearly then I think there would be a large number of grateful readers of both this forum and (the dreaded) C# forum.
 
It's a poor performer, it doesn't work well in many situations, and there are far better options.

akes me think of someone at work.



Christiaan Baes
Belgium

I just like this --> [Wiggle] [Wiggle]
 
<thread safe manor

So, like, since a manor is fancier than an apartment, does that mean that a thread safe manor is more thread safe than an apartment thread?

I think I get it, but I'm not sure.......

 
Well, it was your pun! LOL Thanks for the laugh. This is a great thread, guys! Very informative.

By the way, anyone who wants to get into the real nitty gritty of multithreading might read Dan Appleman's outstanding chapter on it in Moving to VB.Net: Strategies, Concepts, and Code (Apress, 2003).

Bob
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top