异步优于同步的可能方法
Possible ways to do async over sync
我有一个 ASP.NET API 公开了一些数据库操作。 DB API 本身是同步的,不能改变。我知道在 ASP.NET 中使用 Task.Run 是个坏主意,我打算让网络 API 同步,但开始考虑使数据库操作异步的不同可能方式并想知道如果这些是个好主意。
- 使用
Task.FromResult
[HttpGet]
public async Task<Result> Get()
{
return Task.FromResult(DBOperation());
}
感觉除了result之外再分配Task
就好了。
- 使用
ValueTask
return new ValueTask<Result>(DBOperation());
感觉和Task一样(多分配点)?不确定 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
}
也许吧?
你怎么看?
wonder if any of these is a good idea.
没有。
每次尝试在 ASP.NET 上进行异步同步都会导致额外的内存开销。其中一些(Task.Run
和 Task.Yield
)还会导致额外的线程切换。
异步代码的全部意义在于释放一个线程,但如果您有一个不可避免的阻塞调用,那么根据定义,线程不能被释放。正如 Panagiotis 指出的那样,您也许可以用异步调用替换阻塞调用,但如果不行,那么异步同步对您没有帮助。
我有一个 ASP.NET API 公开了一些数据库操作。 DB API 本身是同步的,不能改变。我知道在 ASP.NET 中使用 Task.Run 是个坏主意,我打算让网络 API 同步,但开始考虑使数据库操作异步的不同可能方式并想知道如果这些是个好主意。
- 使用
Task.FromResult
[HttpGet]
public async Task<Result> Get()
{
return Task.FromResult(DBOperation());
}
感觉除了result之外再分配Task
就好了。
- 使用
ValueTask
return new ValueTask<Result>(DBOperation());
感觉和Task一样(多分配点)?不确定 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
}
也许吧?
你怎么看?
wonder if any of these is a good idea.
没有。
每次尝试在 ASP.NET 上进行异步同步都会导致额外的内存开销。其中一些(Task.Run
和 Task.Yield
)还会导致额外的线程切换。
异步代码的全部意义在于释放一个线程,但如果您有一个不可避免的阻塞调用,那么根据定义,线程不能被释放。正如 Panagiotis 指出的那样,您也许可以用异步调用替换阻塞调用,但如果不行,那么异步同步对您没有帮助。