我应该使用与异步操作的方法等待? [英] Should I use await with async Action method?

查看:128
本文介绍了我应该使用与异步操作的方法等待?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在我的控制器长期运行的外部API调用来实现一个非同步动作。

在看一些教程,我已经实现了我的方法是这样的:

  [AsyncTimeout(200)
    公共异步任务<&的ActionResult GT; DoAsync()
    {
        //执行长时间运行的电话。
        返回查看();
    }

我的问题是,这是足以让是真正的无阻塞异步?难道我还需要应用的await运营商,如果是我应该怎么做呢?


解决方案

  

我需要实现我的控制器长期运行的外部API调用的非同步动作。结果......结果
  我的问题是,这是足以让是真正的无阻塞异步?难道我还需要应用的await运营商,如果是我应该怎么做呢?


C#编译器可能已经暗示异步关键字是多余的位置:

  [AsyncTimeout(200)
公共异步任务<&的ActionResult GT; DoAsync()
{
    //执行长时间运行的电话。
    返回查看();
}

您已经添加了异步关键字不会使你的方法在后台运行神奇的事实。

如果你做类似等待Task.Run(()=>查看())通过的另一个答案,你还是不会通过给定的HTTP请求的界限打破。请求处理至少需要尽可能多的时间来产生查看因为没有 Task.Run 。客户端浏览器将仍然在等待它。

此模式是很好的一个用户界面的应用程序,当你需要卸载CPU密集型工作提高到一个池中的线程,避免阻塞UI线程并保持UI响应。但是,使用它的一个ASP.NET应用程序内的HTTP请求处理程序中是几乎从来没有一个好主意。它只会伤害的性能和可扩展性。

一个解决方案,为当查看花费的时间来撰写显著量友好的用户体验,是为运行横跨边界后台任务一个HTTP请求即可。然后再使用AJAX请求,以保持客户端浏览器的最新进展。这里是由Alan D.杰克逊一个很好的例子,正是这样做的:

长时间运行的后台任务在Asp.Net MVC3

然而,运行相同的ASP.NET服务器进程中跨多个HTTP请求一个漫长的后台操作的不可以一个非常好的主意。虽然这是比较容易实现的,这种方法可能会造成与IIS的可维护性,可扩展性和安全性问题。

您可能是一个单独的更好在Windows / WCF服务为,这会暴露一个工作基于API。然后使用AJAX来定期轮询WCF服务,使用ASP.NET MVC控制器的专用方法作为轮询呼叫代理。

I need to implement an asynch Action in my Controller for a long running external API call.

Looking at some tutorials, I have implemented my method like this:

    [AsyncTimeout(200)]
    public async Task<ActionResult> DoAsync()
    {
        // Execute long running call.
        return View();
    }

My question is, is this enough to make is truly non-block asynchronous? Do I also need to apply the await operator, and if so how should I do that?

解决方案

I need to implement an asynch Action in my Controller for a long running external API call.
...
My question is, is this enough to make is truly non-block asynchronous? Do I also need to apply the await operator, and if so how should I do that?

The C# compiler is probably already suggesting the async keyword is redundant here:

[AsyncTimeout(200)]
public async Task<ActionResult> DoAsync()
{
    // Execute long running call.
    return View();
}

The fact that you've added the async keyword doesn't make your method magically run in the background.

If you do something like await Task.Run(() => View()) as suggested by another answer, you still won't break through the boundaries of a given HTTP request. The request processing will take at least as much time to generate the View as without Task.Run. The client-side browser will still be waiting for it.

This pattern is good for a UI app, when you need to offload a CPU-bound work to a pool thread, to avoid blocking the UI thread and keep the UI responsive. However, using it within an HTTP request handler inside an ASP.NET app is almost never a good idea. It will only hurt the performance and scalability.

One solution, providing a user-friendly experience for when the View takes significant amount of time to compose, is to run a background task which spans the boundary of a single HTTP requests. Then further use AJAX requests to keep the client-side browser updated with the progress. Here's a great example by Alan D. Jackson, doing just that:

Long Running Background Tasks in Asp.Net MVC3.

However, running a lengthy background operation across multiple HTTP requests inside the same ASP.NET server process is not a very good idea. While it's relatively easy to implement, this approach may create issues with IIS maintainability, scalability and security.

You might be better off with a separate Windows/WCF service for that, which would expose a Task-based API. Then use AJAX to periodically poll the WCF service, using a dedicated method of your ASP.NET MVC controller as a proxy for the polling call.

这篇关于我应该使用与异步操作的方法等待?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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