简体   繁体   中英

How can I send the HTTP response back to the user but still do more things on the server after that?

Sometimes there is a lot that needs to be done when a given Action is called. Many times, there is more that needs to be done than what needs to be done to generate the next HTML for the user. In order to make the user have a faster experience, I want to only do what I need to do to get them their next view and send it off, but still do more things afterwards. How can I do this, multi-threading? Would I then need to worry about making sure different threads don't step on each others feet? Is there any built in functionality for this type of thing in ASP.NET MVC?

As others have mentioned, you can use a spawned thread to do this. I would take care to consider the 'criticality' of several edge cases:

  • If your background task encounters an error, and fails to do what the user expected to be done, do you have a mechanism of report this failure to the user?
  • Depending on how 'business critical' the various tasks are, using a robust/resilient message queue to store 'background tasks to be processed' will help protected against a scenario where the user requests some action, and the server responsible crashes, or is taken offline, or IIS service is restarted, etc. and the background thread never completes.

Just food for though on other issues you might need to address.

How can I do this, multi-threading?

Yes!

Would I then need to worry about making sure different threads don't step on each others feet?

This is something you need to take care of anyway , since two different ASP.NET request could arrive at the same time (from different clients) and be handled in two different worker threads simultaneously. So, any code accessing shared data needs to be coded in a thread-safe way anyway, even without your new feature.

Is there any built in functionality for this type of thing in ASP.NET MVC?

The standard .net multi-threading techniques should work just fine here (manually starting threads, or using the Task features, or using the Async CTP, ...).

It depends on what you want to do, and how reliable you need it to be. If the operaitons pending after the response was sent are OK to be lost, then .Net Async calls, ThreadPool or new Thread are all going to work just fine. If the process crashes the pending work is lost, but you already accepted that this can happen.

If the work requires any reliable guarantee, for instance the work incurs updates in the site database, then you cannot use the .Net process threading, you need to persist the request to do the work and then process this work even after a process restart (app-pool recycle as IIS so friendly calls them).

One way to do this is to use MSMQ. Other way is to use the a database table as a queue . The most reliable way is to use the database activation mechanisms, as described in Asynchronous procedure execution .

You can start a background task, then return from the action. This example is using the task Parallel Library, found in .NET 4.0:

public ActionResult DoSomething()
{
    Task t = new Task(()=>DoSomethingAsynchronously());
    t.Start();

    return View();
}

I would use MSMQ for this kind of work. Rather than spawning threads in an ASP.NET application, I'd use an Asynchronous out of process way to do this. It's very simple and very clean.

In fact I've been using MSMQ in ASP.NET applications for a very long time and have never had any issues with this approach. Further, having a different process (that is an executable in a different app domain) do the long running work is an ideal way to handle it since your web application is no being used to do this work. So IIS, the threadpool and your web application can continue to do what they need to, while other processes handle long running tasks.

也许你应该试一试: 在ASP.NET MVC中使用异步控制器

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