In continuation of this question.

So let's have a few asynchronous methods.

async Task DoFoo() { ... } async Task DoBar() { ... } async Task DoBaz() { ... } 

which in another asynchronous method

 async Task DoJob() { //TODO: perform DoFoo, DoBar and DoBaz in parallel } 

required to run in parallel.

If you follow the answers in the above question, then to parallel the execution of several asynchronous methods, you need to call them like this:

 async Task DoJob() { Task t1 = DoFoo(); Task t2 = DoBar(); Task t3 = DoBaz(); await Task.WhenAll(t1, t2, t3); } 

In the TaskScheduler documentation, however, I read:

If you’re not a problem, you’ll have to do it. However, tasks that have been created are differently, but differently. It is a queuing task. It can be a child. For this is what it looks like it’s ready for more work.

With regard to the situation, if I understand correctly, tasks t1, t2, t3 are not root-level tasks (because they are nested in a DoJob ), and therefore, starting, they do not end up in a global queue that is processed by multiple pool threads, but - in the local queue of any one particular thread.

It turns out that the multithreaded execution of several asynchronous methods does not provide such a method?

Yes, work stealing can happen, but is it worth Task.Run(...) on it, or to achieve concurrency, it is better to wrap all methods in Task.Run(...) (which will send tasks to be executed on a thread pool, i.e., apparently, global queue )

 async Task DoJob() { Task t1 = Task.Run(DoFoo); Task t2 = Task.Run(DoBar); Task t3 = Task.Run(DoBaz); await Task.WhenAll(t1, t2, t3); } 

?

    1 answer 1

    Right here I will highlight in bold:

    Asynchrony! = Multithreading. Tasks! = Multithreading.

    First, there may be no multithreading if all methods return ready-made tasks.

    Secondly, the advantage of asynchronous methods is that the flow is not blocked during an IO request and that IO requests can easily be executed in parallel (for example, because they are different subsystems of your computer or different computers somewhere on the network).

    A "regular" asynchronous method consists of some synchronous prolog, one or several asynchronous calls with synchronous code between them, and a synchronous epilog. In this method, the execution time of synchronous code and asynchronous correlate as, for example, 1 to 100 (because IO is slow, very slow).

    Thus, running parallel to N asynchronous methods, you save on accessing IO. First of all, IO requests will be executed in parallel. And the fact that one penny of synchronous code in these methods can be executed in one thread should not worry you.

    So, yes, concurrently running asynchronous methods can be executed without using additional threads, but such an implementation still makes sense. Especially when these methods are true asynchronous methods.

    On this topic:

    • Well, we must also add that the nested or child tasks is a completely different mechanism, not connected with the code given by the author. - Pavel Mayorov
    • @PavelMayorov, Task t1 = DoFoo(); Doesn’t it spawn a detached child task? - i-one
    • @andreycha, In the question I didn’t seem to equalize the things highlighted != . The only thing that I thought equated is multithreading and parallelism, but this is also the situation in the original question. - i-one
    • @ i-one is primarily about asynchrony. In this case, there is absolutely no need to compare anything with multithreading. And it is parallel or sequential, it does not matter. - andreycha
    • 2
      @ i-one the tasks generated by this method are executed where you execute them - Pavel Mayorov