LA.NET [EN]

Apr 05

Today we’re going to keep looking at the MVC framework and we’ll see how we can use the “event” pattern for invoking an action asynchronously. This pattern is really simple. You start by adding two methods: the first is responsible for kicking off the asynchronous processing and the second will be called when all the asynchronous actions complete (as you’ll see, with this approach you can start several asynchronous actions). The ending method’s name should follow a specific convention: it must end with the word Completed (where XXX is the name of the action method that is exposed by your controller) and it should return the ActionResult object responsible for kicking off the view rendering phase.

When you opt for this approach, you’ll have to notify the framework whenever you start an asynchronous task (and you also need to signal its end). In practice, this means that you’ll have to increment the AsyncManager’s OutsandingOperations property whenever you start an asynchronous action. And then you’ll also have to decrement this property when that async operation is completes. Internally, this property delegates to a counter and when that counter reaches 0, the platform will automatically invoke your XXXCompleted method.

Your XXXCompleted method might also receive parameters that are automatically fed with the values that might have been added to the AsyncManager’s Parameters property. In practice, when the platform invokes the XXXCompleted method, it will try to match the expected XXXCompleted parameters with values that might exists on the AsyncManager’s Parameters property. Those parameters which don’t exist in that Parameters property get their default value (default(T)).

The restrictions presented for the IAsyncResult pattern applies to this option too. That means that filters must be applied to the begin method (and not to the end method) and that the end method must match the real method name (instead of an eventual alias name that might have been applied to that method). Enough theory…it’s time to show some code. We’re going to reuse the previous example and change it so that we apply this pattern:

public void GetHtml(String url) {
  var req = WebRequest.Create(url);
  req.Method = "GET";
  AsyncManager.OutstandingOperations.Increment(); 
  req.BeginGetResponse(
                (ar) =>
                {
                    var response = req.EndGetResponse(ar);
                    using (var reader = new StreamReader(response.GetResponseStream())) {
                        AsyncManager.Parameters["contents"] = reader.ReadToEnd();
                    }
                    AsyncManager.OutstandingOperations.Decrement();
                },
                        null);
}

public ActionResult GetHtmlCompleted(String contents) {
  ViewData["contents"] = contents;
  return View("Index");
}

There are a couple of interesting observations that you can take from this example:

  • we increment the OustandingOperations before kicking the asynchronous operation;
  • at the end of the callback method, we decrement the OutstandingOperations. When it reaches 0, the GetHtmlCompleted method is called;
  • notice that we use the Parameters property to set the contents parameter value. btw, if we wanted we could also add an entry to the ViewData dictionary instead of doing that in the XXXCompleted method.

Even though the sample has only kicked off one asynchronous operation,nothing prevents you from starting several asynchronous operations. The only thing you can’t forget to do is to keep track of the current running asynchronous operations by incrementing and decrementing the OutstandingOperations property.

And that’s it for today. More about asynchronous

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>