Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding the use of Task.Run + Wait() + async + await used in one line

Tags:

c#

async-await

I'm a C# newbie, so I'm struggling to understand some concepts, and I run into a piece of code that I'm not quite understanding:

static void Main(string[] args)
{
 Task.Run(async () => { await SomeClass.Initiate(new Configuration()); }).Wait();
 while (true) ;
}

As I understand, this runs a task which initiates a method. This method runs, and then, once it finished, it gets into an infinite loop waiting. It feels that either the code doesn't make sense, or that I'm not understanding right.

Thanks

like image 969
Pdon Avatar asked Sep 21 '16 17:09

Pdon


People also ask

What does await Task Run do?

As you probably recall, await captures information about the current thread when used with Task. Run . It does that so execution can continue on the original thread when it is done processing on the other thread.

What is Task in async and await?

The async keyword turns a method into an async method, which allows you to use the await keyword in its body. When the await keyword is applied, it suspends the calling method and yields control back to its caller until the awaited task is complete.

How does Task run work?

The main purpose of Task. Run() is to execute CPU-bound code in an asynchronous way. It does this by pulling a thread from the thread pool to run the method and returning a Task to represent the completion of the method.

Why is async await used?

await can be used on its own with JavaScript modules. Note: The purpose of async / await is to simplify the syntax necessary to consume promise-based APIs. The behavior of async / await is similar to combining generators and promises. Async functions always return a promise.


1 Answers

You can break this apart into several parts:

async () => { await SomeClass.Initiate(new Configuration()); }

Is a lambda expression that defines an async method that just awaits another method. This lambda is then passed to Task.Run:

Task.Run(async () => { await SomeClass.Initiate(new Configuration()); })

Task.Run executes its code on a thread pool thread. So, that async lambda will be run on a thread pool thread. Task.Run returns a Task which represents the execution of the async lambda. After calling Task.Run, the code calls Task.Wait:

Task.Run(async () => { await SomeClass.Initiate(new Configuration()); }).Wait();

This will block the main console app until the async lambda is completely finished.

If you want to see how it's broken out further, the following is roughly equivalent:

static async Task AnonymousMethodAsync()
{
  await SomeClass.Initiate(new Configuration());
}

static void Main(string[] args)
{
  var task = Task.Run(() => AnonymousMethodAsync());
  task.Wait();
  while (true) ;
}
like image 82
Stephen Cleary Avatar answered Sep 18 '22 15:09

Stephen Cleary