2

Let's consider this code :

var tasks = actionItems.Select(t => DoSmthAsync());
var resultAll = await Task.WhenAll(tasks);

And method:

public async Task<int> DoSmthAsync()
{
    Debug.WriteLine("Threadid=" + Thread.CurrentThread.ManagedThreadId);
    var result = await DoSmthAnotherAsync();
    Debug.WriteLine("ThreadId=" + Thread.CurrentThread.ManagedThreadId);
    return result;
}

I expect that this will be executed parallel in different threads, but I see that it work in the same thread. Also, I don't understand when a task run?

4
  • 3
    Hi, asynchrony does not mean parallelism, so expectation to use different threads is not correct. See stackoverflow.com/questions/14099520/… Commented Dec 12, 2019 at 17:31
  • Can you post the code for DoSmthAnotherAsync? Commented Dec 12, 2019 at 19:39
  • What kind of application is this? Console application? Windows Forms? Commented Dec 12, 2019 at 20:56
  • The bigger question is why do you care about threads using async? Async reduces thread usage. Commented Dec 12, 2019 at 21:21

2 Answers 2

3

You're confusing the async await model with parallel programming.

Select will iterate over your actionItems serially. DoSmthAsync will return control to the caller (the Select iterator in this case) when you await DoSmthAnotherAsync and so you get a list of Task<int> created on one thread.

To run the Select statement in paralell, you'll need to use PLINQ.

var tasks = actionItems.AsParallel().Select(t => DoSmthAsync());

This will produce your anticipated results.

You will then need to await Task.WhenAll(tasks); to wait for the results of the tasks. Then you can access the result of each Task<int> in your tasks list with their respective Result properties.

Sign up to request clarification or add additional context in comments.

2 Comments

The AsParallel will only start the tasks in parallel. The OP is probably interested in the whole execution of the tasks, from start to completion.
It seems like his priority is that computation occurs on multiple threads. I've edited my post to include a method to retrieve the results of the tasks.
2

I expect that this will be executed parallel in different threads.

This was explained in Victor Wilson's answer, so I'll focus on explaining only this:

Also, I don't understand when a task run?

A Task is usually started when it is created (in which case it is called a hot task). Async methods and all built-in .NET APIs return hot tasks. It is possible to create a non-started Task by using the Task constructor (creating a so called cold task), but these tasks are normally started internally by the same library that created them. Exposing a cold task to the external world, end expecting the callers to Start it, is something that I have never seen, and it would be highly surprising (in an unpleasant way) if existed.

This constructor should only be used in advanced scenarios where it is required that the creation and starting of the task is separated.

var tasks = actionItems.Select(t => DoSmthAsync());

This line of code doesn't create any tasks, so no task is started at this point. The Select LINQ method returns a deferred enumerable sequence, not a materialized collection. The actual materialization of the tasks happens when you call the method Task.WhenAll(tasks).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.