简体   繁体   English

异步任务 <IActionResult> vs任务 <T>

[英]async Task<IActionResult> vs Task<T>

I have a controller with one action. 我有一个控制器一个动作。 In this action method, I have an async method that I call and that is it. 在这个动作方法中,我有一个我调用的async方法,就是这样。 This is the code that I am using: 这是我正在使用的代码:

[HttpGet]
public Task<MyObject> Get()
{
    return _task.GetMyObject()
}

This serializes correctly into the JSON I expect from it. 这正确地序列化为我期望的JSON。 Now my manager insists that the signature should be changed to the following: 现在我的经理坚持要将签名更改为以下内容:

[HttpGet]
public async Task<IActionResult> Get()
{
    var data = await_task.GetMyObject();
    return Ok(data);
}

I'm of the belief that there is no reason for the code to await in the controller and can just return the Task because nothing afterwards depends on the result. 我相信没有理由在控制器中await代码并且可以返回Task因为之后没有任何东西取决于结果。 Apart from the extra code generation (creation of state machine etc.) done for the await , are there any implications from a WebApi point of view of these approaches? 除了为await做的额外代码生成(创建状态机等)之外, WebApi对这些方法的观点是否有任何影响? To clarify, I want to know if returning an IActionResult is better than to just return Task<MyObject> even tho it seems like the results are the same. 为了澄清,我想知道返回IActionResult是否比返回Task<MyObject>更好,即使结果看起来是相同的。

Task< T> 任务<T>

Pro

Unit tests do not require any casting, 单元测试不需要任何铸造,

 Product product = await controller.Get();

Big advantage is, your unit tests become truly independent of underlying HTTP Stack. 最大的优点是,您的单元测试真正独立于底层HTTP堆栈。

Swagger does not need any extra attribute to generate response schema as swagger can easily detect result type. Swagger不需要任何额外的属性来生成响应模式,因为swagger可以轻松地检测结果类型。

Another big advantage is, you can reuse your controller in some other controller when the logic remains same. 另一个很大的优点是,当逻辑保持不变时,您可以在其他控制器中重用控制器。

Also avoiding await before return gives slight improvement in performance as that part of code does not need Task state machine. 在返回之前避免await性能略有提高,因为该部分代码不需要任务状态机。 I think future C# version will omit single await as compiler optimization. 我认为未来的C#版本将省略单个等待编译器优化。

Con 精读

Returning error status code requires throwing exception.. 返回错误状态代码需要抛出异常..

    throw new HttpStatusException(404, "File not found");
    throw new HttpStatusException(409, "Unauthorized");

Task< IAsyncResult> 任务<IAsyncResult>

Pro

You can return HTTP Status code such as 您可以返回HTTP状态代码,例如

 return NotFound(); // (Status Code = 404)
 return Unauthorized(); // (Status Code = 409)

Con 精读

Unit testing requires extra casting.. 单元测试需要额外的铸件..

 Product productResult = ((await controller.Get()) as OkResult).Result as Product;

Due to such casting, it becomes difficult to reuse your controllers in some other controller, leading to duplication of logic. 由于这种转换,很难在其他控制器中重用控制器,导致逻辑重复。

Swagger generator requires extra attribute to generate response schema Swagger生成器需要额外的属性来生成响应模式

 [ProducesResponseType(typeof(Product), 200)]

This approach is only recommended when you are dealing with logic that is not part of unit tests, and not part of your business logic such as OAuth integration with third party services where you want to focus more on IActionResult based results such as Challenge , Redirect etc. 只有在处理不属于单元测试的逻辑时,才建议使用此方法,而不是业务逻辑的一部分,例如OAuth与第三方服务的集成,您希望更多地关注基于IActionResult的结果,例如ChallengeRedirect等。

Actions can return anything, mostly they return an instance of IActionResult (or Task<IActionResult> for async methods) that produces a response. 动作可以返回任何内容,主要是返回产生响应的IActionResult (或异步方法的Task<IActionResult> )实例。 The action method is responsible for choosing what kind of response it return and the action result does the responding. action方法负责选择返回的响应类型以及响应的操作结果。

If an action returns an IActionResult implementor and the controller inherits from Controller, developers have many helper methods corresponding to many of the choices. 如果一个动作返回一个IActionResult实现者并且控制器继承自Controller,那么开发人员有许多与许多选择相对应的辅助方法。 Results from actions that return objects that are not IActionResult types will be serialized using the appropriate IOutputFormatter implementation. 返回非IActionResult类型对象的操作的结果将使用适当的IOutputFormatter实现进行序列化。

For non-trivial actions with multiple return types or options (for example, different HTTP status codes based on the result of operations performed), prefer IActionResult as the return type. 对于具有多个返回类型或选项的非平凡操作(例如,基于所执行操作的结果的不同HTTP状态代码),更喜欢IActionResult作为返回类型。

ASP.NET MVC is a conventions over configuration framework. ASP.NET MVC是一种基于配置框架的约定 This means any future maintainer of your code, including your future self, will expect code to be written a certain way in order to reduce the number of class files you have to inspect to make changes or additions. 这意味着您的代码的任何未来维护者,包括您未来的自我,都希望代码能够以某种方式编写,以减少您必须检查以进行更改或添加的类文件的数量。

While the result may be the same from your two technically different options, the conventional approach is to async/await your results. 虽然结果可能与您的两个技术上不同的选项相同,但传统方法是异步/等待您的结果。 Anything other than that convention will potentially cause confusion for future maintainers. 除了该约定之外的任何其他内容都可能会对未来的维护者造成混淆。 Additionally, future releases of MVC may break your code in unknown ways as you did not follow the convention. 此外,未来版本的MVC可能会以未知的方式破坏您的代码,因为您没有遵循惯例。

Good leadership of software development teams includes instilling a desire to reduce overall manpower needs for the organization by simplifying potential future maintenance of the code. 软件开发团队的良好领导包括通过简化代码的潜在未来维护来灌输降低组织总体人力需求的愿望。 Your manager may be trying to promote this concept. 您的经理可能正试图推广这一概念。

ASP.NET Core team, while unifying MVC and WEB API (Controller and ApiController), abstracted IActionResult for robust exception handling mechanism. ASP.NET核心团队在统一MVC和WEB API(Controller和ApiController)的同时,抽象了IActionResult以实现强大的异常处理机制。

Throwing exceptions for control flow is an anti-pattern on action methods. 抛出控制流的异常是对行动方法的反模式。

[HttpGet]
public async Task<MyObject> Get()
{
    var data = await _task.GetMyObject()
    if(data == null)
    {
        return NotFound(); //Or, return Request.CreateResponse(HttpStatusCode.NotFound)
        // Versus, throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    }

    return Ok(data);
}

Note: NotFound() , Ok() etc. are IHttpActionResult things in WEBAPI2 era not new to asp.net core. 注意: NotFound()Ok()等是WEBAPI2时代的IHttpActionResult事物并不是asp.net核心的新手。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM