Alternatives to Thread.Sleep()
You have to call WaitOne
on a WaitHandle
, certainly. It's an instance method. Otherwise how would it know what to wait for?
It's definitely better to have something you can react to instead of sleep, so that you can notice cancellation without waiting minutes for no reason. Another alternative to WaitHandle
is to use Monitor.Wait
/Pulse
.
However, if you're using .NET 4 I'd look into what the Task Parallel Library has to offer... it's at a slightly higher level than the other options, and is generally a well thought out library.
For regular work tasks you might want to look at using a Timer
(either System.Threading.Timer
or System.Timers.Timer
) or possibly even Quartz.NET.
Precision alternative to Thread.sleep()
So your solution is not good because of a few issues. You're losing the advantage you gain from using a scheduled executor service by using await
await is going to put the current thread to sleep, and then the os will need to schedule it again before it starts.
I've made an example using three different techniques. A spin wait, using thread.sleep and using your scheduled executor idea. The spin wait is the most accurate, at 7002ms where the other two solutions are over 8300ms when finished.
import java.util.concurrent.*;
public class DwellTimes{
static public void spinWait(long ms){
long end = System.nanoTime() + ms*1000000;
long current = System.nanoTime();
while( current < end){
current = System.nanoTime();
}
}
static public void sleepWait(long ms){
try{
Thread.sleep(ms);
} catch(Exception e){
throw new RuntimeException(e);
}
}
static ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
static public void scheduleWait(long ms){
try{
CountDownLatch l = new CountDownLatch(1);
ses.schedule(l::countDown, ms, TimeUnit.MILLISECONDS);
l.await();
} catch(Exception e){
throw new RuntimeException(e);
}
}
public static void main(String[] args){
long start = System.currentTimeMillis();
for(int i = 0; i<1000; i++){
scheduleWait(7);
}
long end = System.currentTimeMillis() - start;
System.out.println( end + "ms elapsed");
}
}
For a sleep/wait style of flow, the spin wait will be the most accurate because it doesn't release the Thread. It's just going to continue running hot.
The problem with your scheduled executor example is that you're not actually using the scheduling. You want to schedule your tasks.
public static void scheduleWork(){
CountDownLatch latch = new CountDownLatch(1000);
ses.scheduleAtFixedRate(latch::countDown, 7, 7, TimeUnit.MILLISECONDS);
try{
latch.await();
} catch(Exception e){
throw new RuntimeException(e);
}
}
This last example is probably the best way to manage consistent timing because you won't continue to accumulate errors. Eg, if your action takes a couple ms, the next action will not be delayed unless those couple of ms exceed the period.
Is there a alternative to Thread.sleep in java
Is there a alternative to Thread.sleep
Yes, there are ways. But,
It looks like you want to schedule some job. You can either use TimerTask or ScheduledExecutorService instead of this. So later part of your question is about the
"Invoking Thread.sleep in loop can cause performance problems"
and this will solve with scheduling the task.
Scheduling the Task.
public class Test extends TimerTask{
public static void main(String[] args) {
Test task = new Test();
Timer timer = new Timer();
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 13);
today.set(Calendar.MINUTE, 47);
today.set(Calendar.SECOND, 0);
timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
}
@Override
public void run() {
System.out.println("Running Scheduled Task...!!!");
}
}
Alternative to Thread.Sleep in C#?
Your software would freeze if that sleep is on the main thread. Keep in mind the parameter is in milliseconds. 10 800 000 milliseconds = 10 800 seconds
Another way to pass the time is to pass a TimeSpan object instead. Ex:
// Sleep for 10 seconds
System.Threading.Thread.Sleep(new TimeSpan(0, 0, 10));
As for timer:
You can use System.Timers.Timer
;
Timer timer = new Timer();
timer.Interval = 20; // milliseconds
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.AutoReset = true; // if not set you will need to call start after every event fired in the elapsed callback
timer.Start();
Alternatives to using Thread.Sleep for waiting
The WaitHandle
type and derived types provide an event-driven mechanism for waiting that ties into the operating system. For example, when you have a Task<T> task
and you wait on the result by accessing task.Result
, the internal implementation isn't polling with Thread.Sleep
calls in between. It's using a WaitHandle
-derived type to do waiting and synchronization.
Sometimes a polling-based approach is necessary, as in some of the examples you gave in your bullet list, but often you can use an event-driven approach instead. It's not that Thread.Sleep
is always bad - it's just that it is very often misused.
It is just the nature of software to wait for other things in a multi-threaded environment with external factors affecting your code, sometimes you need to wait...
To wait is fine. To wait with polling is often not (*). If there is any way you can use an event-driven wait, you should typically strive to use that.
I don't have a very good feel for exactly what it is that you're asking, so I won't elaborate beyond this. If you leave a comment I can expand my answer.
(*) The theoretical reason waiting with polling is bad is as follows:
Suppose I have code that looks like this:
//START
Begin();
while (!Done())
Thread.Sleep(D);
//STOP
Begin()
starts some operation. Done()
returning true
means the operation has finished. Suppose this will happen after approximately T
time. Then:
- The thread wakes up and checks the condition (calls
Done()
)T/D
times - The duration from
START
toSTOP
includes an expectedD/2
purely because of theThread.Sleep
What value of D
should you choose? As you increase D
, the expected duration form START
to STOP
increases linearly. As you decrease D
, the (bound on the) number of iterations increases as 1/D
. Both of these are bad, and finding the right D
is problematic.
Now compare this to an event-driven wait:
//START
Begin();
WaitDone();
//STOP
Theoretically speaking, as long as WaitDone()
somehow magically waits until the operation has finished but no longer, both of the problems identified in the waiting with polling case have disappeared: this thread waits for exactly the right amount of time - no more, no less!
To reiterate the point I started with: in .NET, the WaitHandle
class and derived types are what facilitate this approach.
Alternative for Thread.Sleep() to temporarily suspend program
async / await to the rescue:
private async void OnButtonClick(object sender, EventArgs e)
{
listBox1.Items.Clear();
listBox1.Items.Add("3");
await Task.Delay(1000);
listBox1.Items.Add("2");
await Task.Delay(1000);
listBox1.Items.Add("1");
await Task.Delay(1000);
listBox1.Items.Clear();
}
How to interrupt Thread.sleep. Alternatives?
Thread.sleep
is non-cancelable and blocks a thread. And spinning on a RunLoop
is inefficient. That having been said, there are a few alternatives:
Nowadays, to manage dependencies between asynchronous tasks, we would reach for Swift concurrency’s
Task
rather thanOperation
. In Swift concurrency, we haveTask.sleep
, which, unlikeThread.sleep
, is cancelable and does not block the thread.If you want to stay within
OperationQueue
patterns, you would use an asynchronous customOperation
subclass (perhaps theAsynchronousOperation
shown in either here or here), and then you would use a timer. You could use aDispatchSourceTimer
, or aTimer
, orasyncAfter
with a cancelableDispatchWorkItem
. Which you choose really does not matter. The key is to ensure that thecancel
implementation invalidates theTimer
or cancels theDispatchWorkItem
orDispatchSourceTimer
, e.g.:class OneSecondOperation: AsynchronousOperation {
weak var timer: Timer?
override func main() {
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { [weak self] _ in
self?.finish()
}
}
}
override func cancel() {
super.cancel()
timer?.invalidate()
finish()
}
}Note, the pattern whereby you periodically check
isCancelled
only applies if you have an existing loop. E.g., if you are doing some iterative calculation, for example, that is a very reasonable pattern. But if you are just waiting, the idea of introducing a loop merely to checkisCancelled
is inefficient. Instead, set up a timer and implementcancel
method that cancels that timer, as shown above.
Either way, you want implementation that does not block a thread and can be canceled. With Operation
subclass you have to implement that yourself. With Swift concurrency, you get that for free.
Related Topics
Inheritance with Base Class Constructor with Parameters
How to Get the Full Url of the Page I am on in C#
Why Func<T,Bool> Instead of Predicate<T>
What's the Difference Between Returning Void and Returning a Task
What Is the Use for Task.Fromresult<Tresult> in C#
How to Make the Value of a Variable Track the Value of Another
How to Change the Background Color of All Other Forms from One Form
Repository Pattern Step by Step Explanation
What Is the Fastest Way to Create a Checksum for Large Files in C#
How to Run and Interact with an Async Task from a Wpf Gui
Identityserver4 Register Userservice and Get Users from Database in ASP.NET Core
Dynamic Routes from Database for ASP.NET MVC Cms