Punit
Punit

Reputation: 1445

Async Await with Task.Run method for DB call

We have an async/await method GetLoanDataAsync which calls a stored procedurre through entity framework which is being called by a sync method GetData.

GetLoanData takes a good amount of time to execute and probably that was the reason that we wrote as async/await which can be used by multiple places.

I understand that we shouldn't mix async and sync calls but let's say if we have this scenario and we are using Task.Run() to call async method GetLoanDataAsync from sync method GetData which I understand that method - GetLoanDataAsync will run on a background thread.

My question is that what if we had a sync version of async method GetLoanDataAsync and called using Task.Run() from GetData than what difference it would make in this case?

Providing more details regarding the issue-

We have ASP.NET REST Web API which return type is not a Task. This is called from angular app. This api has few methods called GetData() and where we wait for the result from GetLoanDataAsync. As per my understanding GetLoanDataAsync will be called in background thread and will be able to execute GetUserDetails(), once this finish it will give back the result from executed GetLoanDataAsync.

Code -

public List<int> GetData(int id)
{

    // Calls GetLoanDataAsync

    var result = Task.Run(()=> GetLoanDataAsync(id));

    // calls couple other sync methods

    GetUserDetails(); 

    return result.GetAwaiter().GetResult();

}

GetLoanDataAsync().Result will result in deadlock which was the earlier issue. To fix this we are temporarily trying to use Task.Run till we make overall api as an async.

Upvotes: 1

Views: 1529

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062770

If you compare a sync vs async version, then the most obvious difference is that the sync version is tying up a thread for the duration of the DB call, which seems unnecessary if all the work is at the database. Whether this is a problem depends on your throughput.

By using Task.Run, you're allowing that operation to run in parallel with other work. This is fine, as long as you don't have any touch-points that impact thread-safety, or which depend on a single logical execution flow.

If you want to use async effectively, it is best to consider it "sticky" - i.e. if X is async, then everything that calls X (directly or indirectly) needs to be async.

Upvotes: 4

Related Questions