简体   繁体   中英

System.Threading Sleep function help? (C#)

I'm new in C# and I'm using System.Threading.

I have this code:

UISystem.SetScene(Scene_Menu);
Thread.Sleep (9000);
p.Text="HELLO";
Thread.Sleep(9000);
p.Text="WORLD";

It delays 18 seconds, but the p.Text="HELLO" doesn't show between the sleep functions. What's the problem with my code?

Thanks.

Timers don't work since I can't edit p from a separate thread.

Application.DoEvents() is a Windows Forms function, I'm building an application in PS Vita.

You have discovered why you should never use Thread.Sleep . It is useful for only two things. (1) Writing test cases that need to simulate a thread being busy for a certain number of seconds, and (2) Sleeping for zero milliseconds tells the operating system "I cede the rest of my time slice to another process if there exists one that wants it"; it's a politeness thing.

You should never use thread.Sleep to introduce a delay as you are doing for exactly the reason you have discovered. You are setting a property, but setting a property does not cause the operating system to repaint the screen . Consider if it did; you might have a thousand property sets in a method, and you would have to repaint the screen after all of them, which would look ugly and be very slow.

Instead what happens is the property is set and the object makes a note to the operating system that says when this thread is available to handle operating system messages again, please repaint me . Your program is, instead of telling the operating system "I'm done, go ahead and see if there are any message for me" that instead you want the thread to do nothing for nine seconds.

Now, you can tell the program to check for messages by calling DoEvents but using DoEvents is also a bad idea and you should not do it . Doing so essentially causes your program to exhibit symptoms of Attention Deficit Disorder; you have not finished the current job and you are looking to see if there are new jobs to do without removing the old jobs from the call stack! Suppose those new jobs in turn get interrupted, and so on, and so on. The stack grows without bound, which is very bad. DoEvents is a "worst practice", just like sleeping a thread. You can get away with it in small simple programs but it leads to big trouble when the program becomes complex.

Moreover: yes, DoEvents will paint your control, but that is all it will do. For the next nine seconds, the application will appear to the user to be completely hung. That is a very bad user experience.

The right thing to do if you want to introduce a delay is to asynchronously wait . In C# 4 and earlier the standard way to do that is to create a timer, and when the timer ticks, do the next thing.

Now, you say that you cannot use a timer because you need to access the control from the UI thread. That's fine. The timer's tick event handler will run on the UI thread, not on a separate thread. You can safely use a timer.

In C# 5, the right thing to do is to use the new await keyword to introduce an asynchronous wait . That is, a wait that does other stuff while it is waiting , instead of going to sleep while it is waiting . In C# 5 you would write your code as:

UISystem.SetScene(Scene_Menu); 
await Task.Delay (9000); 
p.Text="HELLO"; 
await Task.Delay(9000); 
p.Text="WORLD"; 

C# 5 is at present in beta; for details on this new feature see:

http://msdn.microsoft.com/en-us/async

For a gentle introduction to async and an explanation of why DoEvents is bad news, see my MSDN magazine article:

http://msdn.microsoft.com/en-us/magazine/hh456401.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM