Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task continuation parallel execution with async/await

In the context of a console application making use of async/await constructs, I would like to know if it's possible for "continuations" to run in parallel on multiple threads on different CPUs.

I think this is the case, as continuations are posted on the default task scheduler (no SynchronizationContext in console app), which is the thread pool.

I know that async/await construct do not construct any additional thread. Still there should be at least one thread constructed per CPU by the thread pool, and therefore if continuations are posted on the thread pool, it could schedule task continuations in parrallel on different CPUs ... that's what I thought, but for some reason I got really confused yesterday regarding this and I am not so sure anymore.

Here is some simple code :

public class AsyncTest
{
  int i;

  public async Task DoOpAsync()
  {
    await SomeOperationAsync();

    // Does the following code continuation can run 
    // in parrallel ?
    i++;       

    // some other continuation code ....
  }

  public void Start()
  {
    for (int i=0; i<1000; i++)
    { var _ = DoOpAsync(); } // dummy variable to bypass warning
  }
}

SomeOperationAsync does not create any thread in itself, and let's say for the sake of the example that it just sends some request asynchronously relying on I/O completion port so not blocking any thread at all.

Now, if I call Start method which will issue 1000 async operations, is it possible for the continuation code of the async method (after the await) to be run in parallel on different CPU threads ? i.e do I need to take care of thread synchronization in this case and synchronize access to field "i" ?

like image 834
darkey Avatar asked Jan 22 '13 16:01

darkey


People also ask

Does async await run in parallel?

In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() .

When should I use task ContinueWith?

The ContinueWith function is a method available on the task that allows executing code after the task has finished execution. In simple words it allows continuation. Things to note here is that ContinueWith also returns one Task. That means you can attach ContinueWith one task returned by this method.

Does async await use thread pool?

Await Keyword Basically, it returns to caller thread with reference to ongoing task and stop execution of code below that line and release the current thread to thread pool to process another request. Async and await are always used together, if not, then there will be something wrong.

Is task WhenAll concurrent?

WhenAll has designed to handle concurrent I/O bound Tasks with higher scalability as it uses asynchronous non-blocking way to share threads to handle concurrent requests. But, on the other hand, Parallel itself is synchronous. So it is beneficial to use it in CPU bound logics to get better performance.


2 Answers

Yes, you should put thread synchronization logic around i++ because it is possible that multiple threads would be executing code after await at the same time.

As a result of your for loop, number of Tasks will be created. These Tasks will be executed on different Thread Pool threads. Once these Tasks are completed the continuation i.e. the code after the await, will be executed again on different Thread Pool threads. This makes it possible that multiple threads would be doing i++ at the same time

like image 56
Haris Hasan Avatar answered Oct 13 '22 00:10

Haris Hasan


Your understanding is correct: in Console applications, by default continuations will be scheduled to the thread pool due to the default SynchronizationContext.

Each async method does start synchronously, so your for loop will execute the beginning of DoOpAsync on the same thread. Assuming that SomeOperationAsync returns an incomplete Task, the continuations will be scheduled on the thread pool.

So each of the invocations of DoOpAsync may continue in parallel.

like image 35
Stephen Cleary Avatar answered Oct 13 '22 00:10

Stephen Cleary