1

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.

12
  • 1
    What do you do with the result of Task.Run()? Do you wait for the Task to be completed? If yes, then this is not really different from using a sync version in the first place. Commented Nov 21, 2019 at 16:57
  • What kind of app is this for? Web? Winforms? Service? Commented Nov 21, 2019 at 16:58
  • 2
    Remember that asynchronous != parallel. Asynchronous means that the thread is freed while it waits. Parallel means 2 or more things are happening at the same time (on different threads). Task.Run will put it on a different thread. Since it's an async method, the waiting happens nowhere. Commented Nov 21, 2019 at 17:03
  • Seeing actual code would help. What does GetData look like? How it is called? What kind of application is it (desktop, web, etc.)? Commented Nov 21, 2019 at 17:06
  • If this is in a web context, this is a bad idea, because ASP.NET has a limited thread pool and Task.Run() will take up one of those precious threads. If the database call is truly async and you are calling it from a synchronous/blocking thread, then your best bet is to say var result = GetLoanDataAsync().Result. Commented Nov 21, 2019 at 19:22

1 Answer 1

4

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.

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

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.