I know there is Thread.Sleep
and System.Windows.Forms.Timer
and Monitor.Wait
in C# and Windows Forms. I just can't seem to be able to figure out how to wait for X seconds and then do something else - without locking the thread.
I have a form with a button. On button click a timer shall start and wait for 5 seconds. After these 5 seconds some other control on the form is colored green. When using Thread.Sleep
, the whole application would become unresponsive for 5 seconds - so how do I just "do something after 5 seconds"?
The Delay method is typically used to delay the operation of all or part of a task for a specified time interval.
In . NET, Task. Run is used to asynchronously execute CPU-bound code.
An async keyword is a method that performs asynchronous tasks such as fetching data from a database, reading a file, etc, they can be marked as “async”. Whereas await keyword making “await” to a statement means suspending the execution of the async method it is residing in until the asynchronous task completes.
(transcribed from Ben as comment)
just use System.Windows.Forms.Timer. Set the timer for 5 seconds, and handle the Tick event. When the event fires, do the thing.
...and disable the timer (IsEnabled=false) before doing your work in oder to suppress a second.
The Tick event may be executed on another thread that cannot modify your gui, you can catch this:
private System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); private void StartAsyncTimedWork() { myTimer.Interval = 5000; myTimer.Tick += new EventHandler(myTimer_Tick); myTimer.Start(); } private void myTimer_Tick(object sender, EventArgs e) { if (this.InvokeRequired) { /* Not on UI thread, reenter there... */ this.BeginInvoke(new EventHandler(myTimer_Tick), sender, e); } else { lock (myTimer) { /* only work when this is no reentry while we are already working */ if (this.myTimer.Enabled) { this.myTimer.Stop(); this.doMyDelayedWork(); this.myTimer.Start(); /* optionally restart for periodic work */ } } } }
Just for completeness: with async/await, one can delay execute something very easy (one shot, never repeat the invocation):
private async Task delayedWork() { await Task.Delay(5000); this.doMyDelayedWork(); } //This could be a button click event handler or the like */ private void StartAsyncTimedWork() { Task ignoredAwaitableResult = this.delayedWork(); }
For more, see "async and await" in MSDN.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With