Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
726 views
in Technique[技术] by (71.8m points)

c# - Alternatives to Thread.Sleep()

Every N minutes we want to run through a list of tasks. So we've created a task executor with a

do { DoWork(); }while(!stopRequested)

Now we want to have a pause between work cycles. Everyone seems to think Thread.Sleep() is the devil. I've seen mention of using Monitor/Event stuff but we don't have someone else telling us to do work. We just want to do stuff every N minutes like clockwork.

So is there an alternative or have I found a valid use of Thread.Sleep?

Someone in another post mentioned WaitHandle.WaitOne() as an alternative but you can't call that from a non-static method apparently? Or at least I can't because I get a compile time error of..

An object reference is required for the non-static field, method, or property 'System.Threading.WaitHandle.WaitOne(System.TimeSpan)'

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

By my understanding, Thread.Sleep() is bad because it forces the thread's resources out of the cache, so they have to be loaded again afterwards. Not a big deal, but it could aggravate performance issues in high-load situations. And then there's the fact that the timing isn't precise, and that it effectively can't wait for durations under about 10ms...

I use this snippet:

new System.Threading.ManualResetEvent(false).WaitOne(1000);

Easy as pie and it all fits on one line. Creates a new event handler that will never be set, and then waits the full timeout period, which you specify as the argument to WaitOne().

Although, for this specific scenario, a Timer would probably be a more appropriate approach:

var workTimer = new System.Threading.Timer(
    (x) => DoWork(),
    null,
    1000, // initial wait period
    300000); // subsequent wait period

Then, instead of setting a cancel variable, you would stop the timer with workTimer.Stop().


Edit:

Since people are still finding this useful, I should add that .NET 4.5 introduces the Task.Delay method, which is even more concise and also supports async:

Task.Delay(2000).Wait(); // Wait 2 seconds with blocking
await Task.Delay(2000); // Wait 2 seconds without blocking

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...