Home > front end >  Possible ways to do async over sync
Possible ways to do async over sync

Time:01-19

I have an ASP.NET API which exposes some DB operations. DB API itself is synchronous and can't be changed. I'm aware that using Task.Run in ASP.NET is a bad idea and I was going to make the web API sync but started to think about different possible ways about making DB operations async and wonder if any of these is a good idea.

  1. Use Task.FromResult
[HttpGet]
public async Task<Result> Get()
{
      return Task.FromResult(DBOperation());
}

This feels like it'd only be good just to allocate Task in addition to result.

  1. Use ValueTask
return new ValueTask<Result>(DBOperation());

Feels same as Task (just allocate more)? Not sure if ValueTask being struct would be better or worse.

  1. Use TaskCompletionSource
public Task<Result> DBOperation()
{
    TaskCompletionSource<Result> tcs = new TaskCompletionSource<Result>();
    //db call
    tcs.SetResult(<result>);
    return tcs.Task;
}

Not sure if it'd help.

  1. Use Task.Yield
public Task<Result> DBOperation()
{
    await Task.Yield();
    //db call
}

Maybe?

What do you think?

CodePudding user response:

wonder if any of these is a good idea.

Nope.

Every attempt at async-over-sync on ASP.NET causes additional memory overhead. And some of them (Task.Run and Task.Yield) also cause an additional thread switch.

The whole point of asynchronous code is to free up a thread, but if you have an unavoidable blocking call, then the thread can't be freed, by definition. As Panagiotis pointed out, you might be able to replace the blocking call with an asynchronous one, but if not, then async-over-sync won't help you.

  •  Tags:  
  • Related