简体   繁体   中英

await task in each iteration of a loop

What I want to do:

I have a service with a timer that performs a certain sequence of actions every x seconds. In some cases, one of the actions will have to be awaited (in the real life scenario, this is an answer from someone through a chat server).

What I have tried below works, the only problem is that this piece of code:

string result = await WaitAsynchronouslyAsync();

only gets awaited the first time, after the inital wait period, it just puts out one line every second (which is not what I want)

here's my code:

 static void Main(string[] args)
        {
            _timer.Start();
            _timer.Interval = 1000;
            _timer.Elapsed += _timer_Elapsed;
            _timer.Enabled = true;
            Console.Read();
        }

        static async void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //this has to be done every second, regardless of the await below              
            Console.WriteLine(DateTime.Now + " - " + "Current iteration: " + GetNumber++); 

            //this needs to be awaited everytime (in real life this is waiting for a response from a user)
            string result = await WaitAsynchronouslyAsync();
            Console.WriteLine(result);
        }

        public static  async Task<string> WaitAsynchronouslyAsync()
        {
            await Task.Delay(5000);
            var x = GetAsyncNumber ++;
            return x.ToString();
        }

Basically what I want is that the await inside the _timer_Elapsed method happens everytime (so every second it should wait for 5 seconds) and not just one time for 5 seconds, and then every second. I tried out some things with Task.WhenAll() but I don't really understand that and it also does not what I need.

The _timer_Elapsed method gets invoked every second, and each time it will start a new asynchronous task in response to the WaitAsynchronouslyAsync() method call. Since this async task takes 5 seconds to complete and a new async task is spawned every second, you will have up to 5 concurrent* tasks running at once. Then once the first async task completes (after 5 seconds) the second async task only has one second left before it completes. And so on.

The key thing here is that you have multiple asynchronous tasks running at the same time, and the _timer_Elapsed method is always going to be called every second regardless of any asynchronous tasks that may be running from a previous invocation. Also, _timer_Elapsed doesn't return a Task (and can't here anyway because it is an event handler) so the caller has no knowledge of any asynchronous tasks that may have started from inside the method. The method returns before the task has completed.

*Note that these tasks may not necessarily be running on separate threads, so I'm using the word "concurrent" loosely here. See this for more information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM