简体   繁体   English

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

[英]How to make an async call not prevent action from returning response to user

I have the following async code 我有以下异步代码

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);
    }
}

Which is called by the controller action. 这是由控制器动作调用的。

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

SendAsync(some-valid-url);

// Do something

return View();
}

When i debug it - it runs async and hits 当我调试它 - 它运行异步和命中

return View(); return View();

and exits before it is comes to 并且在它出现之前退出

response.Close(); response.Close();

But in fiddler you can see that the http response is not sent by the browser and it waits for the SendAsync function to finish processing, which is not what i want. 但是在提琴手中,你可以看到浏览器没有发送http响应,它等待SendAsync功能完成处理,这不是我想要的。 I want the http response to return back to the user right away. 我希望http响应立即返回给用户。

What do I have to change here to achieve that? 为了达到这个目的,我有什么需要改变的?

i actually edited it and am now doing async static void since i do not need to track the end of the task, 我实际上编辑了它,现在正在执行async static void,因为我不需要跟踪任务的结束,

But you do need to keep track, as MVC will close the connection when Details returns, you need to tell MVC you are waiting for a background action. 但是你确实需要跟踪,因为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();
}

To answer your updated comment 回答您的最新评论

doing an await will make it wait for the async http call to finish. 进行等待将使其等待异步http调用完成。 Which i do not want. 我不想要的。

To get the behavior you are looking for you need to use AJAX , the async/await system will not give you what you want by itself. 要获得您正在寻找的行为,您需要使用AJAX ,async / await系统不会为您提供您想要的东西。 (I have never really done MVC with AJAX so I don't have a example for you how to do it) (我从来没有真正使用AJAX完成MVC所以我没有给你一个例子如何做到这一点)

doing an await will make it wait for the async http call to finish. 进行等待将使其等待异步http调用完成。 Which i do not want. 我不想要的。

It sounds to me like you want fire and forget since you don't want to wait for the response. 这听起来像你想要fire and forget因为你不想等待响应。

There are a few negative points to bare in mind (such as no error handling, no guarantees, etc), so I would recommend reading into this a bit before dropping it into your project. 要记住一些负面因素(例如没有错误处理,没有保证等),所以我建议在将其放入项目之前先阅读一下。

This is, in my opinion, is the easiest way to call a method with fire and forget . 在我看来,这是用fire and forget方法的最简单方法。

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

This will request an available thread from the app pool. 这将从应用程序池中请求可用的线程。 It will then use that thread to execute the method without blocking your current running one. 然后,它将使用该线程执行该方法,而不会阻止当前正在运行的方法。

I hope this helps. 我希望这有帮助。

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

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