在webapi中使用异步等待的最佳实践 [英] best practice for using async await in webapi

查看:417
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆