Reputation: 15
the code shown below is executed inside an asp.net mvc application
public async Task<string> GetCustomers1(){
return await getcustomer1Async();
}
public async Task<string> GetCustomers2(){
return await getcustomer2Async();
}
public async Task<JsonResult> Index(){
var result1 =Task.Run(()=>GetCustomers1());
var result2 =Task.Run(()=>GetCustomers2());
Task.WaitAll(result1,result2);
}
I am clear that task run will create two threads to execute methods GetCustomers1, GetCustomers2. - my question is when the method GetCustomers1 and GetCustomers2 reach the line that has the word await, should the incomplete task be returned, where should the incomplete task be returned? Does the thread return to the thread pool? -Task.WaitAll would you have the main thread busy until the other tasks finish running?
I know you shouldn't use tak.run if the method is asynchronous. But I want to know how the code works internally in such a scenario.
Upvotes: 0
Views: 881
Reputation: 456477
I am clear that task run will create two threads to execute methods GetCustomers1, GetCustomers2.
Task.Run
doesn't create threads. It queues work to the thread pool.
my question is when the method GetCustomers1 and GetCustomers2 reach the line that has the word await, should the incomplete task be returned, where should the incomplete task be returned? Does the thread return to the thread pool?
Yes, the thread is returned to the thread pool. When the await
is ready to resume execution, the "continuation" of that method is queued to the thread pool. Note that continuations may or may not run on the same thread; they can run on any thread pool thread.
Task.WaitAll would you have the main thread busy until the other tasks finish running?
Yes, that is what Task.WaitAll
will do. It also blocks on asynchronous code, which is not a good idea. It's better to go async all the way.
I know you shouldn't use tak.run if the method is asynchronous.
Using Task.Run
for asynchronous code is fine. But in the general case, you shouldn't use Task.Run
on ASP.NET because it queues work to the thread pool instead of letting ASP.NET have full control of the thread pool. Instead, call the asynchronous code directly and use asynchronous code (Task.WhenAll
) instead of blocking code (Task.WaitAll
):
public async Task<string> GetCustomers1() {
return await getcustomer1Async();
}
public async Task<string> GetCustomers2(){
return await getcustomer2Async();
}
public async Task<JsonResult> Index(){
var result1 = GetCustomers1();
var result2 = GetCustomers2();
await Task.WhenAll(result1, result2);
}
Upvotes: 2
Reputation: 43495
Yes, at the await
line the methods GetCustomers1
and GetCustomers2
will immediately return an incomplete task, assuming that the tasks returned from getcustomer1Async()
and getcustomers2Async()
are incomplete. The await
keyword allows you to write code below the await
line, that will run after the awaited task is completed. In your case there is no code below the await line, so you could just as well return directly the tasks without awaiting them:
public Task<string> GetCustomers1()
{
return getcustomer1Async();
}
Notice that not only the await
keyword is gone, but the async
as well.
As for the Index
method, it should give you a compile-time warning for not having an await
inside a method marked with the async
keyword. You should probably modify it to something like this:
public async Task<JsonResult> Index()
{
var task1 = Task.Run(() => GetCustomers1());
var task2 = Task.Run(() => GetCustomers2());
string[] results = await Task.WhenAll(task1, task2);
//...use the results to create a JsonResult and return it
}
Finally keep in mind that it's common practice to add the suffix Async
to the methods that return a Task
. So the method GetCustomers1
should be renamed GetCustomers1Async
, the Index
should be renamed IndexAsync
etc. You can read the relevant guidelines here.
Upvotes: 0