通过同步进行异步的可能方法

dst*_*str 0 .net c# asynchronous async-await asp.net-core

我有一个 ASP.NET API,它公开了一些数据库操作。DB API 本身是同步的并且无法更改。我知道在 ASP.NET 中使用 Task.Run 是一个坏主意,我本来打算使 Web API 同步,但开始考虑使数据库操作异步的不同可能方法,并想知道其中是否有一个好主意。

  1. 使用Task.FromResult
[HttpGet]
public async Task<Result> Get()
{
      return Task.FromResult(DBOperation());
}
Run Code Online (Sandbox Code Playgroud)

感觉Task除了结果之外,只有分配才是好的。

  1. 使用ValueTask
return new ValueTask<Result>(DBOperation());
Run Code Online (Sandbox Code Playgroud)

感觉和任务一样(只是分配更多)?不确定 ValueTask 是 struct 会更好还是更差。

  1. 使用TaskCompletionSource
public Task<Result> DBOperation()
{
    TaskCompletionSource<Result> tcs = new TaskCompletionSource<Result>();
    //db call
    tcs.SetResult(<result>);
    return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)

不确定是否有帮助。

  1. 使用Task.Yield
public Task<Result> DBOperation()
{
    await Task.Yield();
    //db call
}
Run Code Online (Sandbox Code Playgroud)

或许?

你怎么认为?

Ste*_*ary 5

想知道这些是否是个好主意。

没有。

在 ASP.NET 上进行异步同步的每次尝试都会导致额外的内存开销。其中一些(Task.RunTask.Yield)还会导致额外的线程切换。

异步代码的重点是释放线程,但如果有不可避免的阻塞调用,那么根据定义,该线程就无法被释放。正如 Panagiotis 指出的那样,您也许可以用异步调用替换阻塞调用,但如果不能,那么异步优于同步将无济于事。