我试图在我的Web API项目中使用ASP.NET的 async/await
功能 . 我不确定它是否会对我的Web API服务的性能产生任何影响 . 请在下面找到我的应用程序中的工作流程和示例代码 .
Work Flow:
UI应用程序→Web API endpoints (控制器)→Web API服务层中的调用方法→调用另一个外部Web服务 . (这里我们有数据库交互等)
Controller:
public async Task<IHttpActionResult> GetCountries()
{
var allCountrys = await CountryDataService.ReturnAllCountries();
if (allCountrys.Success)
{
return Ok(allCountrys.Domain);
}
return InternalServerError();
}
Service Layer:
public Task<BackOfficeResponse<List<Country>>> ReturnAllCountries()
{
var response = _service.Process<List<Country>>(BackOfficeEndpoint.CountryEndpoint, "returnCountries");
return Task.FromResult(response);
}
我测试了上面的代码并且正在运行 . 但我不确定它是否正确用于 async/await
. 请分享你的想法 .
4 回答
你没有有效地利用async / await,因为执行同步方法时会阻塞请求线程
ReturnAllCountries()
分配用于处理请求的线程将暂时等待
ReturnAllCountries()
它的工作 .如果您可以实现
ReturnAllCountries()
是异步的,那么您会看到可伸缩性的好处 . 这是因为线程可以释放回.NET线程池来处理另一个请求,而ReturnAllCountries()
正在执行 . 通过更有效地利用线程,这将使您的服务具有更高的吞吐量 .我会将您的服务层更改为:
正如你所拥有的那样,你仍在同步运行你的
_service.Process
呼叫,并且等待它几乎没有任何好处 .使用这种方法,您将在
Task
中包含潜在的慢速调用,启动它,并将其返回等待 . 现在你得到了等待Task
的好处 .请记住,服务器端异步代码的主要好处是可伸缩性 . 它不会神奇地使您的请求运行得更快 . 我在article on async ASP.NET中介绍了几个“我应该使用
async
”的注意事项 .我认为你的用例(调用其他API)非常适合异步代码,请记住"asynchronous"并不意味着"faster" . 最好的方法是首先使你的 UI 响应和异步;这将使您的应用程序感觉更快,即使它稍慢 .
就代码而言,这不是异步的:
您需要一个真正的异步实现来获得
async
的可伸缩性优势:或者(如果你在这个方法中的逻辑真的只是一个传递):
请注意,'s easier to work from the 929669 rather than the 929670 like this. In other words, don' t以异步控制器操作开始,然后强制下游方法异步 . 相反,确定自然异步操作(调用外部API,数据库查询等),并首先将这些异步设置为最低级别(
Service.ProcessAsync
) . 然后让async
涓涓细流,使控制器操作异步作为最后一步 .在任何情况下都不应该在这种情况下使用
Task.Run
.这是正确的,但可能没用 .
由于没有什么可以等待 - 没有调用阻止可以异步操作的API - 然后你正在设置结构来跟踪异步操作(有开销),但后来没有使用该功能 .
例如,如果服务层使用支持异步调用的Entity Framework执行数据库操作:
在查询数据库时,您将允许工作线程执行其他操作(从而能够处理另一个请求) .
Await往往需要一直向下:很难适应现有系统 .