简体   繁体   中英

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

and exits before it is comes to

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. I want the http response to return back to the user right away.

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,

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.

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. 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. (I have never really done MVC with AJAX so I don't have a example for you how to do it)

doing an await will make it wait for the async http call to finish. 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.

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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