Thread.Sleep(300) not working correctly

2019-08-15 19:19发布

I want it to execute the first part of the code, then make the pictureBox visible, pause for 3 seconds, hide the pictureBox and execute the rest of the code:

// first part of the code here
pb_elvisSherlock.Visible = true;
Thread.Sleep(300);
pb_elvisSherlock.Visible = false;
// rest of the code here

But it executes the whole block of code and only then pauses. Any ideas what to do?

Thanks!

7条回答
倾城 Initia
2楼-- · 2019-08-15 19:23

If you are trying to make a PictureBox appear for 3 seconds, you probably want your application to remain responsive during this time. So using Thread.Sleep is not a good idea because your GUI thread does not process messages while sleeping.

A better alternative would be to set a System.Windows.Forms.Timer for 3000 ms, to hide the PictureBox after 3 seconds without blocking your GUI.

For example, like this:

pb.Visible = true;
var timer = new Timer();
timer.Tick += () => { pb.Visible = false; timer.Stop(); };
timer.Interval = 3000;
timer.Start();
查看更多
太酷不给撩
3楼-- · 2019-08-15 19:23

First of all you are only sleeping for 300 milliseconds not 3 seconds

Thread.Sleep(3000);

Second your User interface will first be updated when your code is done executing, so you need to do something like this

查看更多
4楼-- · 2019-08-15 19:25

I would try making this longer:

Thread.Sleep(300);

change to

Thread.Sleep(3000);

You are only pausing for .3 seconds in your example (3000 = 3 seconds). If I had to guess, you aren't waiting long enough for the window to display. The code is actually working correctly.

Like the comment try adding in Application.DoEvents(); after setting the visibility property.

查看更多
可以哭但决不认输i
5楼-- · 2019-08-15 19:25

You can try this Task.Delay(TimeSpan.FromSeconds(3)).Wait(); wherever Thread.Sleep method sometimes doesn't block the thread.

查看更多
迷人小祖宗
6楼-- · 2019-08-15 19:31

The problem is that you are blocking the UI thread, which is the thread responsible for doing the redrawing of your form, so nothing gets redrawen during the 3 seconds you are waiting (Try draging your form around during these 3 seconds and you'll see it's totally unresponsive).

There are loads of ways of dealing with this, but the basic premise is that firstly you need to do your waiting on a background thread so your UI thread remains responsive (Options include using a BackgroundWorker, a Timer, the ThreadPool, a Thread or the TPL TaskFactory). Secondly, you must remember that any update to the UI must be done on the UI thread, so you must switch back to your UI thread (Using .Invoke() or a TaskScheduler) before you hide the picture box at the end.

This example uses the TPL (Task Parallel Library):

// Start by making it visible, this can be done on the UI thread.
pb_elvisSherlock.Visible = true;

// Now grab the task scheduler from the UI thread.
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

// Now create a task that runs on a background thread to wait for 3 seconds.
Task.Factory.StartNew(() =>
{
    Thread.Sleep(3000);

// Then, when this task is completed, we continue...
}).ContinueWith((t) =>
{
    //... and hide your picture box.
    pb_elvisSherlock.Visible = false;

// By passing in the UI scheduler we got at the beginning, this hiding is done back on the UI thread.
}, uiScheduler);
查看更多
Luminary・发光体
7楼-- · 2019-08-15 19:35

Extensions are quite helpful in such situations ;-)

public static class IntExtensions
{
    public static TimeSpan Seconds(this int value)
    {
        return new TimeSpan(0, 0, value);
    }
}

Thread.Sleep(3.Seconds());
查看更多
登录 后发表回答