How to Asynchronously Wait for X Seconds and Execute Something Then

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

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

How to have program wait X seconds and allow UI to execute?

It looks like you have a couple of options

1.You can try Sleep -(but it may hang the UI)

 int Seconds = 1;
Threading.Thread.Sleep(Seconds * 1000);

2.You can try this code:

int Seconds = 1;
Private void WaitNSeconds(int seconds)
{
if (seconds < 1) return;
DateTime _desired = DateTime.Now.AddSeconds(seconds);
while (DateTime.Now < _desired) {
System.Windows.Forms.Application.DoEvents();
}
}

3.Try to use Async and see what happens

async Task MakeDelay() {
await Task.Delay(5000);
}
private async void btnTaskDelay_Click(object sender, EventArgs e) {
await MakeDelay();
}

What happens in long running async method before delay?

I have a method that sends a request to my server every second.

No, you do not. Please do not open questions with false statements; it makes them hard to answer!

Your workflow is:

  • Request data
  • Wait for the data to arrive -- that's what asynchronously wait means. await is asynchronously wait.
  • Once the data has arrived, pause for a second, again, asynchronously
  • Repeat.

That is NOT the workflow "send a request every second". That is the workflow "send a request one second after the last request succeeded".

What does in this time (10 or 15 seconds)?

Asynchronously waits. You said to asynchronously wait until the data was available, and that's what it does. During the asynchronous wait other tasks can be scheduled to execute on the thread.

Will the workflow wait until the long request is completed?

Yes. It will wait asynchronously. Again, that's what await means. It means asynchronously wait.

Will new requests send every second without wait?

No. You said to wait until the data was received and then pause for one second, so that's what happens.

Is there a way to make my code wait a number of seconds before executing the next piece of code? (API Requests Per Second Limit)

Once you are running async functions you will need to use async/await to do that, setTimeout/Sleep wont work.

if you want a request to end when going to the next code you can do it this way:

async function funcName(){
const result = await axios.request(options).then(function (response2) {
message.reply(termargs + " passwords:" + '`' +
JSON.stringify(response2.data.found) + '`');
});

const result2 = await axios.request(options).then(function (response2) {
message.reply(termargs + " passwords:" + '`' +
JSON.stringify(response2.data.found) + '`');
});
}

funcName();

on this example first he will end result 1, than go to solve result 2...

Here is the docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

Asynchronously wait for Task<T> to complete with timeout

How about this:

int timeout = 1000;
var task = SomeOperationAsync();
if (await Task.WhenAny(task, Task.Delay(timeout)) == task) {
// task completed within timeout
} else {
// timeout logic
}

And here's a great blog post "Crafting a Task.TimeoutAfter Method" (from MS Parallel Library team) with more info on this sort of thing.

Addition: at the request of a comment on my answer, here is an expanded solution that includes cancellation handling. Note that passing cancellation to the task and the timer means that there are multiple ways cancellation can be experienced in your code, and you should be sure to test for and be confident you properly handle all of them. Don't leave to chance various combinations and hope your computer does the right thing at runtime.

int timeout = 1000;
var task = SomeOperationAsync(cancellationToken);
if (await Task.WhenAny(task, Task.Delay(timeout, cancellationToken)) == task)
{
// Task completed within timeout.
// Consider that the task may have faulted or been canceled.
// We re-await the task so that any exceptions/cancellation is rethrown.
await task;

}
else
{
// timeout/cancellation logic
}


Related Topics



Leave a reply



Submit