更改我的服务器端WebAPI以获得async / await的好处
试图了解服务器端的异步/等待使用。 我的理解是它只在释放线程时才有用。 如果我有:
[HttpGet] public async Task<IEnumerable> Get() { return await Task<IEnumerable>.Run(() => DoThingsAndGetResults()); } IEnumerable DoThingsAndGetResults() { // ...Do some CPU computations here... IEnumerable result = myDb.table.Select().ToList(); // entity framework // ...Do some CPU computations here... return result; }
线程会被释放吗? 在这种情况下Async / Await是无用的吗? 从async / await获益的唯一方法是,如果我做了一些更大的更改并执行此操作:
[HttpGet] public async Task<IEnumerable> Get() { return await DoThingsAndGetResultsAsync(); } async IEnumerable DoThingsAndGetResultsAsync() { // ...Do some CPU computations here... IEnumerable result = await myDb.table.Select().ToListAsync(); // entity framework // ...Do some CPU computations here... return result; }
如果你想要实现的是释放线程,第二个例子更好。 第一个在整个操作中保持一个线程。
说明
async-await
所做的就是简单地帮助您编写异步运行但“看起来”同步的代码。
异步代码有两个原因:
- 卸货 。 主要用于
GUI
线程或其他“更重要”的线程“。(在等待CPU操作完成时释放线程)。 - 可扩展性 。 主要用于服务器端以减少资源使用。 (在等待IO完成时释放线程)。
不出所料,原因与您的示例相符。
在第一个示例中,您在另一个线程上运行DoThingsAndGetResults
(使用Task.Run
)并等待它以异步方式完成。第一个线程正在释放,但第二个线程没有。
在第二个中,您一次只使用1个线程,并在等待IO(entity framework)时释放它。
当您必须等待IO操作(从文件读取,查询数据库,从Web服务器接收响应)时,异步方法最有用。
例如,当您的数据库提供程序支持像Entity Framework 6这样的异步查询时,可以使用异步。虽然它对CPU绑定操作(计算等)不是很有用。
请参阅ASP.NET MVC4异步控制器的相关答案- 为什么要使用?
使用An异步操作进行长时间运行io操作服务器端的好处之一是,就像数据库调用一样,你可以释放线程请求被处理,以便web服务器有更multithreading可用于处理新请求。 请注意,在使用默认任务计划程序时,这是正确的,该计划程序在线程池中的可用线程上计划任务。 当使用另一个taskcheduler时,效果可能会有所不同……
- DelegatingHandler在WebApi中解压缩传入的请求
- 从MVC的DependencyResolver过渡到AutofacWebApiDependencyResolver – 哪里是.Current?
- ASP.NET Web API – 没有“MediaTypeFormatter”可用于读取“Int32”类型的对象
- ASP.NET Core Identity不会注入UserManager
- 多个可选的查询字符串参数REST API GET
- 任何人都可以使用示例客户端应用程序解释IExceptionHandler的工作流程
- 如何使用客户端证书在Web API中进行身份validation和授权
- 基于角色的安全性在breezejs和EF6中
- 错误:此操作将创建结构不正确的文档