【发布时间】:2022-01-19 20:37:17
【问题描述】:
我有一个 ASP.NET API,它公开了一些数据库操作。 DB API 本身是同步的,无法更改。我知道在 ASP.NET 中使用 Task.Run 是一个坏主意,我打算使 Web API 同步,但开始考虑使数据库操作异步的不同可能方法,并想知道这些是否是个好主意.
- 使用
Task.FromResult
[HttpGet]
public async Task<Result> Get()
{
return Task.FromResult(DBOperation());
}
感觉除了结果之外,只分配Task 就好了。
- 使用
ValueTask
return new ValueTask<Result>(DBOperation());
感觉和Task一样(只是分配更多)?不确定 ValueTask 是 struct 是更好还是更差。
- 使用
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
}
也许?
你怎么看?
【问题讨论】:
-
基于
Get()上的[HttpGet]属性我认为在这里引入异步而不是同步没有意义,只需将操作的返回类型更改为Result。 -
这些都是错误的,它们实际上是同步的。
Task.Run实际上是一个更好的选择,我也不建议这样做,因为您可能会遇到跨多个线程访问数据库的并发问题。 -
就像 2012 年的 Stephen Toub said:不要。
-
只返回值。 Web 请求已经由单独的线程处理,因此所有选项都只会浪费 CPU 周期。如果 IO(在这种情况下是实际的数据库调用)可以异步执行,您只会从
async/await获得一些东西。如果您的驱动程序不支持真正的异步,请寻找另一个或使用同步操作。例如,MySQL 的 Connector/NET 伪造异步调用,因此每个人都使用真正开源的MySQLConnector.Net。 -
@dstr
DB API itself is synchronous and can't be changed.你确定吗?您正在调用什么数据库以及如何调用?可能有可以异步工作的替代驱动程序
标签: c# .net asp.net-core asynchronous async-await