developer
developer

Reputation: 15

call method async inside Task.Run

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

Answers (2)

Stephen Cleary
Stephen Cleary

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

Theodor Zoulias
Theodor Zoulias

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

Related Questions