在webapi中使用异步等待的最佳实践 [英] best practice for using async await in webapi
问题描述
我有.NET核心Web API作为服务层.服务层具有所有EF代码.
I have .NET core Web API which as service layer. Service layer has all EF code.
如果具有带有此代码的basecontroller
If have basecontroller with this code
protected Task<IActionResult> NewTask(Func<IActionResult> callback)
{
return Task.Factory.StartNew(() =>
{
try
{
return callback();
}
catch (Exception ex)
{
Logger.LogError(ex.ToString());
throw;
}
});
}
在控制器动作中,我将所有对服务的调用都包装在上述方法中,例如:
In controller action I wrap all calls to service in above method e.g. :
[HttpGet("something")]
public async Task<IActionResult> GetSomething(int somethingId)
{
return await NewTask(() =>
{
var result = _somethingService.GetSomething(somethingId);
if (result != null)
return Ok(result);
else
return NotFound("Role not found");
});
}
考虑到明天这种正确的模式吗?我可能有多个服务调用正在运行或正在调用其他Web服务.请告知.
Is this correct pattern considering tomorrow I may have more than one service calls in action or making calls to other webservice. Please advise.
推荐答案
我希望我的api从异步等待中受益.上面的模式是否可以满足这些需求
i want my api to benefit from async await thing.does above pattern will serve these needs
不,不是.在线程池上运行同步工作会给您带来同步和异步代码的缺点,而两者都不会有好处.
No, it does not. Running synchronous work on the thread pool gives you the drawbacks of synchronous and asynchronous code, with the benefits of neither.
某项服务有一些使用实体框架核心的简单操作
something service has some crud operations which use entityframework core
当前,您的操作方法就是我所说的伪异步"-它看起来是异步的(例如,使用await
),但实际上只是在后台线程上运行阻塞代码.在ASP.NET上,您想要真正的异步,这意味着您必须一直保持异步.有关ASP.NET上为什么这样不好的更多信息,请参见我的简介的前半部分到async
在ASP.NET文章上(它主要处理ASP.NET非核心,但第一部分讨论同步请求与异步请求对任何类型的服务器均有效).
Currently, your action method is what I call "fake asynchronous" - it looks asynchronous (e.g., using await
), but in fact is just running blocking code on a background thread. On ASP.NET, you want true asynchrony, whicn means you must be async all the way. For more about why this is bad on ASP.NET, see the first half of my intro to async
on ASP.NET article (it mostly deals with ASP.NET non-core, but the first part talking about synchronous vs asynchronous requests is valid for any kind of server).
要使其真正异步,您应该从最低级别开始-在这种情况下,您的EFCore调用.它们都支持异步.因此,将x.FirstOrDefault()
之类的API调用替换为await x.FirstOrDefaultAsync()
(所有创建/更新/删除等操作均应如此).
To make this truly asynchronous, you should start at the lowest level - in this case, your EFCore calls. They all support asynchrony. So, replace API calls like x.FirstOrDefault()
with await x.FirstOrDefaultAsync()
(and the same for all your creates/updates/deletes, etc).
然后允许async
/await
从那里自然生长;编译器将指导您.您最终将在somethingService
上使用异步方法,该方法可以按如下方式使用:
Then allow async
/await
to grow naturally from there; the compiler will guide you. You'll end up with asynchronous methods on your somethingService
which can be consumed as such:
[HttpGet("something")]
public async Task<IActionResult> GetSomething(int somethingId)
{
var result = await _somethingService.GetSomethingAsync(somethingId);
if (result != null)
return Ok(result);
else
return NotFound("Role not found");
}
这篇关于在webapi中使用异步等待的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!