Processing Async Request in ASP.NET MVC

I have an ASP.NET MVC3 application that handles labor-intensive processes (copying a large file from the network). We want to do the following:

  • The user clicks the button to submit the form to start the process.
  • The application launches a new stream to start copying the file.
  • The application displays a message about the start of the file copying process.
  • The user can close the browser when the copy is processed and finished in the background.

The idea is that the user does not need any confirmation of the progress of the process and is not informed when the process is completed.

We currently allow the controller to fire an event in the Windows service and use the Windows service to do the actual work. I am wondering if there is a better / cleaner way to do this?

+6
source share
3 answers

You can use System.Threading.Tasks.Task by calling the StartNew method with a delegate.

Using these tools, your controller will look something like this:

[HttpPost] public ActionResult DoSomethingLongRunning() { if (ModelState.IsValid) { Task.Factory.StartNew(() => fileCopier.CopyFile(CopyFileParameter1, CopyFileParameter2)); return RedirectToAction("View Indicating Long Running Progress"); } else { // there is something wrong with the Post, handle it return View("Post fallback view"); } } 

Another option is that you can use System.Reactive.Concurrency and IScheduler with TaskPoolScheduler as a specific implementation to perform an action (possibly entered into the controller’s constructor.

 public ActionResult DoSomethingLongRunning() { if (ModelState.IsValid) { ISchedulerImplementation.Schedule(new Action(() => { fileCopier.CopyFile(CopyFileParameter1, CopyFileParameter2); })); return RedirectToAction("View Indicating Long Running Progress"); } else { // there is something wrong with the Post, handle it return View("Post fallback view"); } } 

As an advantage, if you do, you can use TestScheduler as an interface implementation for unit testing.

+6
source

I think that with a Windows Service host, your long process is the best choice. If it is hosted on IIS, you always run the risk of running the application pool if it is idle.

One related possibility is to host the WCF service in your Windows service and provide an external HTTP or other endpoint for the service. Thus, your web interface can invoke the β€œrun” contract method of your WCF service, and possibly other methods.

+3
source

I will send the request to the WCF MSMQ service hosted in IIS 7 WAS. There is an amazing article on how to set it up.

Long-term tasks using external resources have a high risk of failure. The biggest mistake developers often make is to assume that equipment and networks have unlimited bandwidth and are very reliable. This is often not the case.

This can be problematic, even catastrophic, if a long process is interrupted by a short-term loss of a network connection or by rebooting a remote server. If your lengthy process involves additional processing, for example, to unzip a file or analyze it, you may run the additional risk of failure if there is not enough memory to complete the processing. Users can submit too many requests and not enough resources to handle concurrent problems. If you let your ASP.NET MVC application process using asynchronous controllers , you may be surprised when your lengthy process is interrupted when IIS is processing the workflow.

MSMQ 4 copes well with these risks. If the process fails, you can repeat it several times before giving up. You can find out how to set up here . You can use special queues for the message queue to handle the case when the process failed with a series of acceptable attempts. It is important for operational staff to diagnose problems. You can also use this scheme to notify the user by email that the process has failed (or succeeded), even if the machine on which the request was made is turned off.

Hosting in IIS, not a Windows service, offers additional features. For example, an IIS workflow can be recycled if it slows down or exceeds a memory threshold. The latter can be a problem when you use native code to perform processing. You can recycle it every four (choose the time). The latter is very important when working with large blocks of managed memory, because over time the head of a large object becomes so fragmented that it becomes almost impossible to control the allocation of sufficient memory for another large request. You may find that the WCF service hosted by the Windows service may be affected by this problem.

In reality, it depends on how reliable you want this background process to be. If not, using WCF, MSMQ, and IIS might just be redundant.

+2
source

Source: https://habr.com/ru/post/911841/


All Articles