3

I'm trying to run two methods in parallel. The first method connects to an ftp server and downloads some data. Because I want to reduce the network traffic it should run every 30 s. In parallel I want another method to run independent from the first method every 10 s.

The problem is I don't get the methods running/delayed in parallel.

namespace Example
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await Task.Run(async () =>
            {
                while (true)
                {
                    await Every10s();
                    await Every30s();
                }
            });
        }

        public static async Task<bool> Every10s()
        {
            await Task.Delay(10000);
            Console.Writeline("10s");
            return true;
        }

        public static async Task<bool> Every30s()
        {
            await Task.Delay(30000);            
            Console.Writeline("30s");
            return true;
        }
    }
}

I would expect the following output with the corresponding pauses in between: 10s 10s 10s 30s 10s 10s 10s 30s ...

But instead both methods wait for each other so I get the output 10s 30s 10s 30s 10s 30s with a 40s pause.

Any help and hints are appreciated.

6
  • 2
    Instead of awaiting the Tasks the method return, you should store them in a List and perform await Task.WhenAll(list) on it. You'd need to do that on each while-cycle. Note, for this use case I'd suggest using timers over async/await since this is literally the definiton of a timer. Another reason not to use async/await here is because async/await isn't truly parallel (I'd link to an awesome write up here but I forgot where it's from). Commented Jun 24, 2019 at 12:09
  • You are mixing up parallel execution and asynchronous execution. Async isn't parallel. Commented Jun 24, 2019 at 12:10
  • @iSpain17 very true, forgot to mention that. I'll add it. Commented Jun 24, 2019 at 12:11
  • 2
    How is this program going to end? There is no way of exiting the infinite loop! Commented Jun 24, 2019 at 12:16
  • I forgot where the write up is from but there are so many sources on this like this answer, this question and many more if you search a bit. Commented Jun 24, 2019 at 12:16

1 Answer 1

4

Because I want to reduce the network traffic it should run every 30 s. In parallel I want another method to run independent from the first method every 10 s.

You have two independent loops of work, so you need two loops in your code:

async Task RunEvery10s()
{
  while (true)
    await Every10s();
}

async Task RunEvery30s()
{
  while (true)
    await Every30s();
}

await Task.WhenAll(RunEvery10s(), RunEvery30s());
Sign up to request clarification or add additional context in comments.

8 Comments

When and how will this program terminate?
It will exit when all foreground threads have exited, just like any other program.
But the call to Task.WhenAll won't ever return right? None of the passed in tasks will ever complete so the Task.WhenAll call won't return either or am I missing something?
The WhenAll is a way to observe exceptions. If either of the operations fail, their exception will end up being thrown from await Task.WhenAll.
Thank you! I tried that before but without await methodname(); Works fine. I already implemented cancellation exceptions; the code was just a simplified example.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.