Reputation: 11
In my program there is a loop that only stops if the user presses a certain button. Now I want to give the user a certain amount of time to press the button. I change the color of the button to show the user that the stop-button is now active.
this.button.Focus();
this.button.BackColor = Color.Green;
System.Threading.Thread.Sleep(2000);
// now the loop continues and the button changes its color
this.button.BackColor = Color.White;
It seems like there is not a "real" 2 second stop because the color does NOT to green at all.
Upvotes: 1
Views: 8712
Reputation: 203829
You're blocking the UI thread, and because of that no other updates to the user interface can take place until you free it up again. You need to use asynchrony here; let the UI thread stop executing your method and continue handling other requests.
Fortunately the await
keyword makes doing this much easier than other methods.
First we'll just create a helper method to generate a task that will be completed when a button is clicked:
public static Task WhenClicked(this Button button)
{
var tcs = new TaskCompletionSource<bool>();
EventHandler handler = null;
handler = (s, e) =>
{
tcs.TrySetResult(true);
button.Click -= handler;
};
button.Click += handler;
return tcs.Task;
}
Now we can easily wait until either 2 seconds have passed, or the button is clicked:
public async void Bar()
{
this.button.Focus();
this.button.BackColor = Color.Green;
await Task.WhenAny(Task.Delay(2000), button.WhenClicked());
// now the loop continues and the button changes its color
this.button.BackColor = Color.White;
}
Upvotes: 1
Reputation: 754725
The thread you are putting to sleep is the same thread that is responsible for drawing the application. Hence calling Sleep
here will simply stop application processing. This is definitely not what you want to do.
The better way to approach this problem is to use a Timer
object. Stop the processing, change the button color and setup a Timer
to fire in 2 seconds time. If the button is pressed earlier stop the timer, else if the timer event fires then restart the processing. This method will allow the application to continue to run during the 2 second window
Upvotes: 2
Reputation: 26209
You should not use Thread.Sleep()
as it hangs your UI.
Try This:
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
timer1.Interval=2000;
timer1.Tick += new System.EventHandler(timer1_Tick);
timer1.Start();
private void timer1_Tick(object sender, EventArgs e)
{
//do whatever you want
this.button.BackColor = Color.White;
//Stop Timer
timer1.Stop();
}
Upvotes: 0
Reputation: 101681
It seems your UI
is freezing and you can't see the cahgnes.Instead try this, make your method async
then use await
public async void SomeMethod()
{
this.button.BackColor = Color.Green;
await Task.Delay(2000);
this.button.BackColor = Color.White;
}
Upvotes: 1