1

I have a ASP.Net MVC controller and it calls a method that will post a purchase order. However I want the purchase order posting to take place in the background, I don't want the controller to wait for the purchase order to post before returning. The posting takes a long time and there really is nothing the user of the website can do if there is a error, somebody else needs to be alerted.

It seemed like a good case for using the C# await and async functionality, but I am struggling to get it to work. I tried to setup the method that posts the purchase order as a asynchronous method. However I am running into the following problems:

  • The class that has the method that post the purchase order implements a interface. The controller is using the interface and you cannot put async on a method in a interface. So I tried to resolve this by having the method return a Task.
  • The method to post the purchase order is not running asynchronously, it is running synchronously like a normal method.

What am I doing wrong? Here is the code:

public class POReceivingController : Controller
{
 IPOReceivingService poservice;
 public POReceivingController(IPOReceivingService poserviceparm)
 {
 poservice = poserviceparm;
 }
 public ActionResult PostPO(string shipmentid)
 {
 poservice.PostPOAsync(shipmentid);
 }
}
public interface IPOReceivingService
{
 Task PostPOAsync(string shipmentidparm);
}
public class POReceivingService : IPOReceivingService
{
 public async Task PostPOAsync(string shipmentidparm)
 {
 // Code to post PO and alert correct people if there is an error.
 }
}
Hamlet Hakobyan
33.5k6 gold badges55 silver badges70 bronze badges
asked Jan 23, 2014 at 17:47
4
  • 1
    stackoverflow.com/a/18509424 Commented Jan 23, 2014 at 17:49
  • Link provided by @RobertHarvey have explanation why you should not be doing "fire and forget" methods... If you indeed have long running operations you should consider some additional system that would perform operations and let user to track progress/completion separately. Commented Jan 23, 2014 at 17:54
  • Like a Windows Service. Commented Jan 23, 2014 at 17:54
  • It does sound like I am approaching this the wrong way. I do need to make sure the method completes and does not get killed. I will take a different approach. Thank you for the help. Commented Jan 23, 2014 at 18:13

2 Answers 2

3

As I explain on my blog, async doesn't change the HTTP protocol. Making the controller action async won't cause the response to be sent early.

To do this properly, save the request to a persistent queue (e.g., Azure queue or MSMQ), and have an independent backend (e.g., Azure worker role or Win32 service) that does the processing and failure notificaiton.

answered Jan 23, 2014 at 18:19

Comments

0

You are making this more complicated than it needs to be. If you just want to fire off another thread to do some work for you and not worry about it all you need to do is something list this:

public ActionResult PostPO(string shipmentid)
 {
 Task.Run(() => PostPOAsync(shipmentid));
 Return view();
 }
answered Jan 23, 2014 at 21:38

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.