I wish my method to wait about 500 ms and then check if some flag has changed. How to complete this without blocking the rest of my application?
-
9The question is deeply underspecified; we need to know what "the rest of the application" is -- is it running on the same thread, different threads, a different machine, what? That said, almost all of the answers so far are dangerous. Using either DoEvents or Thread.Sleep are worst practices that indicate a badly designed application in danger of nasty re-entrancy bugs. Tudor's answer is the best one: use a timer. – Eric Lippert Dec 13 '11 at 21:59
-
5Also, consider investigating the Async CTP version of C# 5. We have added control flow that lets you very easily delay for 500 milliseconds and pick up where you left off, without blocking any threads or starting up new message loops. – Eric Lippert Dec 13 '11 at 23:30
9 Answers
You can use await Task.Delay(500);
without blocking the thread like Sleep
does, and with a lot less code than a Timer.

- 1,489
- 2
- 21
- 25
-
1This requires .NET 4.5, but if you have to use .NET 4.0 you can use something like this https://stackoverflow.com/a/17717159/5815327 instead. – Deantwo Feb 27 '19 at 13:08
-
1This also requires the function to be Asynchronous. So, if you do not want to do that for some reason, the timer function @Sinjai created works like a charm too. – Nandostyle Jun 03 '23 at 15:32
Thread.Sleep(500)
will force the current thread to wait 500ms. It works, but it's not what you want if your entire application is running on one thread.
In that case, you'll want to use a Timer
, like so:
using System.Timers;
void Main()
{
Timer t = new Timer();
t.Interval = 500; // In milliseconds
t.AutoReset = false; // Stops it from repeating
t.Elapsed += new ElapsedEventHandler(TimerElapsed);
t.Start();
}
void TimerElapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hello, world!");
}
You can set AutoReset
to true (or not set it at all) if you want the timer to repeat itself.
-
3Just a slight correction, the `Interval`property has a value in **milliseconds**, not seconds [link](http://msdn.microsoft.com/en-us/library/system.timers.timer.interval(v=vs.110).aspx) – Mickael V. Mar 10 '14 at 09:55
-
1**current thread** was very helpful. i wrongfully thought that `Thread.Sleep` causes main thread to sleep. – samad montazeri Aug 02 '16 at 17:41
-
2I think you have the use of AutoReset backwards. Setting it to true or not setting it at all has the timer repeat itself. [link](https://msdn.microsoft.com/en-us/library/system.timers.timer.autoreset%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) – JochemKempe May 02 '17 at 11:14
-
@JochemKempe Fixed, though I'm not sure why you didn't do that over a year ago. Just leaving this comment to avoid confusing any future Googlers. – Sinjai Jan 17 '19 at 20:40
I don't really understand the question.
If you want to block before checking, use Thread.Sleep(500);
If you want to check asynchronously every x seconds, you can use a Timer
to execute a handler every x milliseconds.
This will not block your current thread.
-
1
-
1If it's a GUI application, then it's probably best to use the timer specific to the GUI library used (e.g. `DispatcherTimer` in the case of WPF). – svick Dec 14 '11 at 20:52
-
There's a difference between "checking every x seconds" and "waiting x seconds and then checking". I believe the OP wants the latter. – Josh Noe Jan 26 '18 at 20:28
It the method in question is executing on a different thread than the rest of your application, then do the following:
Thread.Sleep(500);

- 7,344
- 3
- 30
- 33
-
@user898569 by definition if you want to "wait for somthing" something needs to sit there "waiting". So no, you must use another thread or it will block your program. See [Tudor's answer](http://stackoverflow.com/a/8496300/80274) for a way to fire a event that will run on the main thread but it will not be "waiting" it will just be a periodic event. – Scott Chamberlain Dec 13 '11 at 21:21
-
Interesting question. I suggest you read up on Asynchronous Programming in .NET. Here's a link to a good starting point: http://msdn.microsoft.com/en-us/vstudio/gg316360 – Phil Klein Dec 13 '11 at 21:25
System.Threading.Thread.Sleep(500);
Update
This won't block the rest of your application, just the thread that is running your method.

- 46,965
- 25
- 159
- 237
-
2Lol, mine took longer than 7 seconds to type because I put in the namespace. Wasn't first :( – danludwig Dec 13 '11 at 21:19
Using a timer should do the trick
if you need to use a thread then here is an example
void Main()
{
System.Threading.Thread check= new System.Threading.Thread(CheckMethod);
check.Start();
}
private void CheckMethod()
{
//Code
Thread.Sleep(500);
}

- 312
- 2
- 11
I've recently been struggling with the same issue where I needed an action to be run on schedule without blocking the UI.
Here's my solution:
private void Button_Click(object sender, RoutedEventArgs e)
{
RunOnSchedule(interval, cancellationToken);
}
private void RunOnSchedule(int interval, CancellationToken cancellationToken)
{
// Start the task you want to run on schedule
TaskToRunOnSchedule(args);
Task.Run(async () =>
{
// This loop checks if the task was requested to be cancelled every 1000 ms
for (int x = 0; x < interval; x+=1000)
{
if (cancellationToken.IsCancellationRequested)
{
break;
}
await Task.Delay(1000);
}
}).GetAwaiter().OnCompleted(() =>
{
// Once the task for delaying is completed, check once more if cancellation is requested, as you will reach this point regardless of if it was cancelled or not.
if (!cancellationToken.IsCancellationRequested)
{
// Run this method again
RunOnSchedule(interval, cancellationToken);
}
});
}

- 9
- 2
In a WinForms application, when I want to wait on the main thread without blocking the app, I usually use
private void Wait (double milliseconds)
{
DateTime next = System.DateTime.Now.AddMilliseconds(milliseconds);
while (next > System.DateTime.Now)
Application.DoEvents();
}

- 135
- 1
- 2
- 6