Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

355
Views
c# async await confuses me, seems to do nothing

EDIT: Updating LongTask() to be await Task.Delay(2000); makes it work how I need, so thanks for the answers, y'all!


I am trying to call an async function from within a sync function to let the sync function keep going before the async function is finished. I don't know why the code below waits for LongTask() to complete before continuing. I thought it should only do that if I did await LongTask(). Can someone help me understand what I'm missing?

C# fiddle here

using System;
using System.Diagnostics;
using System.Threading.Tasks;
                    
public class Program
{
    public static void Main()
    {
        var timer = new Stopwatch();
        timer.Start();
        LongTask();
        timer.Stop();
        
        long ms = timer.ElapsedMilliseconds;

        Console.WriteLine(ms.ToString());
    }
    
    async static void LongTask()
    {
        Task.Delay(2000).Wait();
    }
}
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

As already mentioned in the comments:

you have to use await Task.Delay(2000) to tell the compiler that you want run Task.Delay(2000) asynchronous. If you take a closer look in the example provided by you the compiler shows a warning:

This async methods lacks 'await'operators and will run synchronously [...]

over 4 years ago · Santiago Trujillo Report

0

This will hopefully demonstrate it better:

static async Task Main(string[] args)
{
    var timer = Stopwatch.StartNew();
    var t1 = LongTask();
    var t2 = LongTask();
    Console.WriteLine("Started both tasks in {0}", timer.Elapsed);
    await Task.WhenAll(t1, t2);
    timer.Stop();
    Console.WriteLine("Tasks finished in {0}", timer.Elapsed);
}

async static Task LongTask()
{
    await Task.Delay(2000);
}

Notice the change in return types of functions. Notice the output, too. Both task are waiting for something (in this case delay to expire) in parallel and at the same time, the Main function is able to continue running, printing text and then waiting for the outcome of those functions.

It is important to understand that the execution of an async function runs synchronously until it hits the await operator. If you don't have any await in an async function it will not run asynchronously (and compiler should warn about it). This is applied recursively (if you have several nested awaits) until you hit something that is actually going to be waited for. See example:

static async Task Main(string[] args)
{
    var timer = Stopwatch.StartNew();
    var t1 = LongTask(1);
    Console.WriteLine("t1 started in {0}", timer.Elapsed);
    var t2 = LongTask(2);
    Console.WriteLine("Started both tasks in {0}", timer.Elapsed);
    await Task.WhenAll(t1, t2);
    timer.Stop();
    Console.WriteLine("Tasks finished in {0}", timer.Elapsed);
}

async static Task LongTask(int id)
{
    Console.WriteLine("[{0}] Before subtask 1", id);
    await LongSubTask1();
    Console.WriteLine("[{0}] Before subtask 2", id);
    await LongSubTask2();
    Console.WriteLine("[{0}] After subtask 1", id);
}

async static Task LongSubTask1(int id)
{
    Console.WriteLine("[{0}] LongSubTask1", id);
    await Task.Delay(1000);
}
async static Task LongSubTask2(int id)
{
    Console.WriteLine("[{0}] LongSubTask2", id);
    await Task.Delay(1000);
}

If you run it, you will see that the execution runs synchronously all the way down to Task.Delay call and only then it returns all the way back to the Main function.

In order to benefit from async/await, you have to use it all the way down to where it ends up calling some I/O (network, disk, etc.) you will need to wait for (or some other event that does not require constant polling to figure out, or artificially created like delay in that sample). If you need to do some expensive computation (that does not have anything async in it) without occupying some particular thread (say, UI thread in GUI application), you'd need to explicitly start new task with it, which at some later point you can await for to get its result.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!