我有一个ASP.NET API,它公开了一些DB操作。DB API本身是同步的,不能更改。我知道在ASP.NET中使用Task.Run不是一个好主意,我本打算让web API同步,但我开始考虑让DB操作异步的不同可能方法,并想知道这些方法是否是个好主意。
- 使用
Task.FromResult
[HttpGet]
public async Task<Result> Get()
{
return Task.FromResult(DBOperation());
}
这感觉只有在结果之外分配Task
才是好的。
- 使用
ValueTask
return new ValueTask<Result>(DBOperation());
感觉和任务一样(只是分配更多(?不确定作为结构体的ValueTask是好是坏。
- 使用
TaskCompletionSource
public Task<Result> DBOperation()
{
TaskCompletionSource<Result> tcs = new TaskCompletionSource<Result>();
//db call
tcs.SetResult(<result>);
return tcs.Task;
}
不确定这是否有帮助。
- 使用
Task.Yield
public Task<Result> DBOperation()
{
await Task.Yield();
//db call
}
也许吧?
你觉得怎么样?
想知道这些是否是个好主意。
没有。
每次在ASP.NET上尝试异步过度同步都会导致额外的内存开销。其中一些(Task.Run
和Task.Yield
(也会导致额外的线程切换。
异步代码的全部目的是释放线程,但如果您有一个不可避免的阻塞调用,那么线程就不能被释放。正如Panagiotis所指出的,您可能可以用异步调用替换阻塞调用,但如果不能,那么异步过度同步对您没有帮助。