Sam
Sam

Reputation: 4484

Task.Delay not returning to main thread

I am testing out async/await and here is the problem. I am starting two tasks asynchronously and waiting for their execution to complete. I expect the two tasks to wait for respective delays and then return to print total milliseconds elapsed. But the program is only printing 1 start " + current time and 2 start " + current time but nothing after that. How can I return from the delayed tasks and print the final result?

    static void Main(string[] args)
    {
        RunTasksWithDelays();
    }

    static async void RunTasksWithDelays()
    {
        Stopwatch s = Stopwatch.StartNew();

        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
        Task task1 = LongRunningTask1();
        Task task2 = LongRunningTask2();

        await Task.WhenAll(task1, task2);
        Console.WriteLine("total milliseconds elapsed:  " + s.ElapsedMilliseconds / 1000);

    }

    static async Task LongRunningTask1()
    {
        Console.WriteLine("1 start " + DateTime.Now);
        await Task.Delay(5000);
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
        Console.WriteLine("1 end " + DateTime.Now);

    }

    static async Task LongRunningTask2()
    {
        Console.WriteLine("2 start " + DateTime.Now);
        await Task.Delay(2000);
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
        Console.WriteLine("2 end " + DateTime.Now);

    }

Upvotes: 0

Views: 1847

Answers (2)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

Your main thread ends and thus program ends because there is no foreground thread in your application to keep the program alive.

Ideally you should be awaiting RunTasksWithDelays method but you can't await it for two reasons

  1. Your method doesn't return Task
  2. Main method doesn't support await.

You should make the RunTasksWithDelays method return async Task rather than async void and you should wait for its completion. Waiting synchronously is a bad idea, that's fine in this scenario as we don't have any choices.

static void Main(string[] args)
{
    RunTasksWithDelays().Wait();
}

static async Task RunTasksWithDelays()
{
    ...
}

Upvotes: 4

Chris Sainty
Chris Sainty

Reputation: 9346

Your method RunTasksWithDelays should return a Task for the caller to wait for this task to complete.

Then you can simply call RunTasksWithDelays().Wait();

Upvotes: 2

Related Questions