如何进行异步调用不会阻止操作返回对用户的响应

时间:2014-06-30 18:34:21

标签: c# .net asp.net-mvc asynchronous async-await

我有以下异步代码

public async static void SendAsync(string url)
{
    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.KeepAlive = false;
        request.Timeout = 5000;
        var response = await request.GetResponseAsync().ConfigureAwait(false);
        response.Close();
    }
    catch (Exception ex)
    {
        SendException(ex, url);
    }
}

由控制器操作调用。

public ActionResult Details(string id)
{
// DO something 

SendAsync(some-valid-url);

// Do something

return View();
}

当我调试它时 - 它运行异步并点击

  

返回View();

并在出现之前退出

  

response.Close();

但是在fiddler中你可以看到浏览器没有发送http响应,它等待SendAsync函数完成处理,这不是我想要的。我希望http响应立即返回给用户。

为了达到这个目的,我有什么需要改变的?

2 个答案:

答案 0 :(得分:3)

  

我实际上编辑了它,现在正在执行async static void,因为我没有   需要跟踪任务的结束,

但是你确实需要跟踪,因为MVC将在Details返回时关闭连接,你需要告诉MVC你正在等待后台操作。

public async Task<ActionResult> DetailsAsync(string id)
{
    // DO something 

    var sendTask = SendAsync(some-valid-url);

    // Do something else that does not depend on sendTask

    await sendTask;

    return View();
}

回答您的最新评论

  

进行等待将使其等待异步http调用完成。   我不想要的。

要获得您正在寻找的行为,您需要使用AJAX,async / await系统不会为您提供您想要的内容。 (我从来没有真正使用AJAX完成MVC,所以我没有为你做一个例子)

答案 1 :(得分:0)

  

进行等待将使其等待异步http调用完成。   我不想要的。

听起来像你想要fire and forget,因为你不想等待回复。

要记住一些负面因素(例如没有错误处理,没有保证等),所以我建议您在将其放入项目之前先阅读一下。

在我看来,这是使用fire and forget调用方法的最简单方法。

ThreadPool.QueueUserWorkItem(o => SendAsync(some-valid-url));

这将从应用程序池中请求可用的线程。然后它将使用该线程执行该方法,而不会阻止当前正在运行的方法。

我希望这会有所帮助。