Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to asynchronously wait for x seconds and execute something then?

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"?

like image 306
Dennis G Avatar asked Feb 02 '12 12:02

Dennis G


People also ask

Which method is used for delaying the operation in particular intervals?

The Delay method is typically used to delay the operation of all or part of a task for a specified time interval.

Is Task run asynchronous?

In . NET, Task. Run is used to asynchronously execute CPU-bound code.

What is Task in async and await?

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.


1 Answers

(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.

like image 182
eFloh Avatar answered Oct 02 '22 11:10

eFloh