Sunday, 20 January 2013

Method overloading in TypeScript

TypeScript is observed as an object oriented language. Because of which we expect it to behave just like any other object oriented program out there. One of the key features of any object oriented language is method overloading. The way TypeScript supports this feature is a bit different.

In TypeScript, we cannot create multiple methods with same name in a class. If we attempt to do it, we get an error saying Duplicate identifier <Method name>. It happens even if the methods are defined by following all the rules of method overloading.

The way to achieve method overloading in TypeScript is we have to define a method with highest parameters and declare the other methods. Following sample demonstrates it:

class MyClass
{
 Display(num?: number,name?: string){
  document.write("x is: "+num.toString()+" and y is: "+name);
 }
 Display(num: number);
 Display(name: string);
 Display();
}

As we see, we have defined a Display method with two null able parameters and declared three Display methods with one or no parameters. This code compiles to following JavaScript:
var MyClass = (function () {
    function MyClass() { }
    MyClass.prototype.Display = function (num, name) {
        document.write("x is: " + num.toString() + " and y is: " + name);
    };
    return MyClass;
})();

Yes, there is just one function named Display. Because, a JavaScript function can be called passing all or less number of parameters. This applies to constructor as well.
class MyClass
{
 num: number;
 name: string;
 
 constructor(x?: number,str?: string){
  this.num=x;
  this.name=str;
 }
 constructor(x: number);
 constructor(str: string);
 constructor();
}

This compiles to:
var MyClass = (function () {
    function MyClass(x, str) {
        this.num = x;
        this.name = str;
    }
    return MyClass;
})();

It is important to note that the parameters that have to be omitted in overloads should be marked as nullable in the concrete method. Otherwise, the parameter becomes mandatory and TypeScript compiler reports an error.

Happy coding!

Thursday, 27 December 2012

Friendly URLs in ASP.NET 4.5 Web Forms


In the recent update of ASP.NET, Microsoft released support for Friendly URLs in ASP.NET Web Forms. It is based on the concept of Routing. But, we don’t need to deal with route table to manually add the routes to be mapped. URLs of the site will be automatically made friendly after invoking when the application starts.

To get started using the Friendly URLs, we need to install the NuGet Package Microsoft.AspNet.FriendlyUrls. The package is not stable yet, so we need to search it in pre-release packages.
























This package adds following files to the web application:
  • Microsoft.AspNet.FriendlyUrls assembly – Contains required set of classes and interfaces
  • Site.Mobile.Master – Master page for mobile devices
  • ViewSwitcher.ascx – A user control that can be used to switch views from desktop view to Mobile view and vice versa
Once Visual Studio finishes installing the NuGet package, a read me file will be popped up. This file contains the steps to be followed to enable Friendly URLs on your site. All you have to do is, call the EnableFriendlyUrls extension method of RouteTable in RegisterRoutes method of RouteConfig class. This method is defined in Microsoft.AspNet.FriendlyUrls namespace.
routes.EnableFriendlyUrls();

And make sure that the RegisterRoutes method is called in Application_Start event of Global.asax:
RouteConfig.RegisterRoutes(RouteTable.Routes);

Now run the application and check URL on the address bar of your browser.































And the magic happened! As we see here, the URL doesn’t contain extension of the page.

Note: You don’t have to install NuGet package and apply the above settings if you have installed ASP.NET and Web Tools 2012.2. These changes are built into the ASP.NET web application template in the new template.

If you are using default ASP.NET 4.5 Web application template, you can invoke the Login (which resides in Account folder) page using:

http://mysite/Account/Login

You can link any page that resides in a folder using the same convention.

Hyperlinks to the pages can be replaced with the friendly convention.

<a id="loginLink" runat="server" href="~/Account/Login">Log in</a>

Data can be passed to a page using segments. Href method of FriendlyUrl class can be used for this purpose:
<a href="<%: FriendlyUrl.Href("~/BookDetails","AspNet") %>">ASP.NET</a>

This hyperlink forms the following URL:

http://mysite/BookDetails/AspNet

This data can be displayed on the page in any mark-up element. To display the topic of book sent through the above URL in a span element, we have to get the value from the segment as shown below:

<span><%: Request.GetFriendlyUrlSegments()[0].ToString() %></span>

Also, this value can be passed as a parameter to a method used for Model Binding as shown below:
public IQueryable<Customer> GetBooks([FriendlyUrlSegments]string topic)
{
    var selectedBooks = context.Books.Where(c => c.BookName.Contains(topic));
    return selectedBooks;
}

Remember that, if you are navigating to the page ListBooks.aspx with following URL,

http://mysite/ListBooks/Book/AspNet

then the parameter marked with FriendlyUrlSegments will hold the value Book/AspNet. So, this should be handled with care.

You can also create mobile friendly pages and even pages specific to certain type of device using Friendly URLs. Check Scott Hanselman’s great post on Introducing ASP.NET FriendlyUrls - cleaner URLs, easier Routing, and Mobile Views for ASP.NET Web Forms to learn more
about Friendly URLs and mobile pages.

Happy coding!

Sunday, 23 December 2012

Basics: Routing in ASP.NET Web forms

Many of our friends think that Routing is a feature of ASP.NET MVC and cannot be used with ASP.NET web forms. But the fact is that, Routing is a part of ASP.NET core. It is added to the core in ASP.NET 3.5 SP1. In ASP.NET 4.0, routing is made more developer friendly. So, anything that falls under ASP.NET family can use routing.

Using routing in ASP.NET Web Forms, we can generate URLs that don’t correspond to the physical file. Server will reach the physical file to be rendered using the parameters passed with route URL. Defining pretty URLs makes the pages easily searchable by the search engines.


Using Routing with ASP.NET Web forms

To use routing in an ASP.NET Web Forms application, we have to register the routes when the application starts. This means, the routes have to be registered to System.Web.Routing.RouteTable.Routes collection in the Application_Start event of Global.asax. There are several overloads of MapPageRoute method in RouteCollection, but we usually use the following overload:

public Route MapPageRoute(string routeName, string routeUrl, string physicalFile);

Following is an example of registering a simple route which can be used to hide extension of aspx forms:
routes.MapPageRoute("basic-route", "{page}", "~/{page}.aspx");

Once this route is registered, we can safely replace the URL

http://mysite/Page.aspx

with the following URL:

http://mysite/Page

But, this route doesn’t work if we have some pages in a folder. For example, suppose the web application has a folder named Account and this folder has the forms Login.aspx and Register.aspx, we would expect the page Login.aspx to respond when we hit the URL

http://mysite/Account/Login

But, it doesn’t work as we didn’t define a route for it. We have to add the following route to the route table to make this URL work as we expected:

routes.MapPageRoute("folder-route", "{folder}/{Page}", "~/{folder}/{Page}.aspx");

Now a question arises that, do we need to hard-code the routed URLs in hyperlinks? The answer is no. We can refer to the registered routes by their names and provide values to the route parameters to get the URL generated for us. Following HyperLink generates the URL to Login page we discussed above:
<asp:HyperLink ID="hlLogin" Text="Login" NavigateUrl="<%$ RouteUrl:RouteName=folder-route,folder=Account,page=Login %>" runat="server" />

We can also pass input parameters to a page using route parameters. For example, if we have a page named Book.aspx that lists a set of books on a particular topic and the topic is passed using QueryString to the page as shown below,

http://mysite/Book.aspx?topic=JavaScript

We can avoid usage of QueryString and make the URL prettier as shown below

http://mysite/Book/JavaScript

To achieve this we have to add the following route to the RouteCollection:

routes.MapPageRoute("book", "Book/{BookName}", "~/Book.aspx");

The route value passed to this page can be accessed from both aspx mark-up and from code behind file. Following mark-up demonstrates displaying mark-up value on a label:
<asp:Label ID="lblBookName" Text="<%$ RouteValue:BookName %>" runat="server" />

Following code snippet shows accessing the route value from code behind file:
var bookName = Page.RouteData.Values["BookName"].ToString();

This value can be used to query database or any other type of further processing.

Further learning:
http://msdn.microsoft.com/en-us/magazine/dd347546.aspx 
http://weblogs.asp.net/scottgu/archive/2009/10/13/url-routing-with-asp-net-4-web-forms-vs-2010-and-net-4-0-series.aspx
http://haacked.com/archive/2008/03/11/using-routing-with-webforms.aspx


Happy coding!

Monday, 17 December 2012

A Real-time chart using SignalR and Flot

I have discussed about SignalR in some of my earlier posts. I lately found Flot, a jQuery plugin that makes it very easy to create charts on HTML pages without doing a lot of work. Since both SignalR and Flot are based on jQuery at the client end, they work well together. In this post, we will see how to create a chart showing price of a stock that changes every second.


On Server Side

As we are using SignalR, we need a hub class. To represent a stock value object, we need a class with a couple of properties in it. Following is the StockValue class that we will use to send data to client:
public class StockValue
{
    public int Time { get; set; }
    public double Price { get; set; }
}

For this solution, I have used Visual Studio 2012 and SignalR 1.0 RC. There are a number of changes made to SignalR in this version. Following are the changes that we will be using in this post:

Calling a client function from Server: Clients.All.functionName(data);
Calling a server function from client: proxy.server.functionName(data);
Defining a JavaScript client function: proxy.client.functionName(data);

We need a StockMarket class that does the following tasks:

  • Initializes stock values
  • Updates the stock values after certain period
  • Sends the updated data to all clients
Code of this class is as follows:
public class StockMarket
    {
        public static readonly Lazy<StockMarket> market = new Lazy<StockMarket>(() => new StockMarket());
        static List<StockValue> stockValues;
        Timer _timer;
 
        public static StockMarket Instance
        {
            get
            {
                return market.Value;
            }
        }
 
        public void InitializeStockvalues()
        {
            stockValues = new List<StockValue>()
                {
                    new StockValue(){Time=10,Price=10.4},
                    new StockValue(){Time=20,Price=10.5},
                    new StockValue(){Time=30,Price=10.2},
                    new StockValue(){Time=40,Price=10.5}
                };
            GetClients().All.drawChart(stockValues);
        }
 
        public void GenerateNextStockValue(object state)
        {
            Random randomGenerator = new Random();
            int changeInCost = randomGenerator.Next(100, 110);
 
            var lastStockValue = stockValues[stockValues.Count - 1];
            var nextStockValue = new StockValue();
            nextStockValue.Time = lastStockValue.Time + 10;
            nextStockValue.Price = changeInCost / 10.0;
 
            stockValues.Add(nextStockValue);
 
            GetClients().All.drawChart(stockValues);
        }
 
        public void PublishPrices()
        {
            if (stockValues == null)
            {
                InitializeStockvalues();
            }
            else
            {
                GenerateNextStockValue(null);
            }
            _timer = new Timer(GenerateNextStockValue, null, 1000, 1000);
        }
 
        public IHubConnectionContext GetClients()
        {
            return GlobalHost.ConnectionManager.GetHubContext<StockValuesHub>().Clients;
        }
    }

Finally, we need a Hub class to kick off the process on the server. The hub class is very simple as we have assigned most of the responsibilities to StockMarket class.
public class StockValuesHub : Hub
    {
        public void GetStockValues()
        {
            StockMarket.Instance.PublishPrices();
        }
    }


On Client Side

On the client HTML page, we need to add references to following JavaScript libraries:
  • jQuery library
  • SignalR jQuery library
  • Flot jQuery library
  • Reference to SignalR’s dynamic proxy library

Flot requires a div element to render chart. So, let’s add the following div element to our page:

<div id="canvasChart" style="height: 300px; width: 300px;"></div>

On page load, we need to invoke the GetStockValues() function to start the process.
var hub = $.connection.stockValuesHub;
var dataToChart = [];
 
$.connection.hub.start()
    .done(function () {
        hub.server.getStockValues();
     });

We need to define the drawChart function on client to consume the data sent by server and render the chart. It involves a bit of logic as Flot doesn’t operate on JSON data. We need to convert our data to a form that Flot understands.

Flot accepts values in the form of an array. In the API documentation of Flot, it is specified that, Flot accepts values in the form of an array of a series. Following is an example of the data to be passed into Flot (copied from API documentation):

[ [1, 3], [2, 14.01], [3.5, 3.14] ]

Since SignalR sends JSON data, we need to convert the data to above format before we render the chart. Each object in the collection has to be converted to an array with two elements. Following function does this job for us:

function convertToArray(data) {
    var dataArray = [];
    dataArray.push(data.Time);
    dataArray.push(data.Price);
    return dataArray;
}

Finally, let’s add the drawChart function to client proxy. Implementation of this function is pretty straight forward.
hub.client.drawChart = function (data) {
    if (dataToChart.length == 0) {
        $.each(data, function () {
            dataToChart.push(convertToArray(this));
        });
    }
    else {
        dataToChart.push(convertToArray(data[data.length - 1]));
    }
    $.plot($("#canvasChart"), [dataToChart]);
};


You can download the complete code here.

Happy Coding!

Tuesday, 4 December 2012

Bouncing a ball on HTML5 Canvas

Canvas provides a nice interface to draw anything on it. Canvas doesn’t support animations by default, but as we write JavaScript to do anything on canvas, we can create animations too. Let’s see how we can create a basic animation to bounce a ball inside boundaries of canvas.

Let’s create a ball on the canvas. We can do it by drawing a circle and filling some color inside it. Following code shows how to do it:
function draw(){
    context.beginPath();
    context.fillStyle="green";
    context.arc(10,10,20,0,Math.PI*2,true);
    context.closePath();
    context.fill();
}
Since we have to move the ball on canvas, we may say that we have to draw the ball over and over at different positions. Before drawing the ball at next position, we must clear the ball already drawn. And this logic has to be repeated after certain time.

Let’s modify the draw function defined above to draw the ball at different positions. The logic involves:
  • Clearing the canvas
  • Drawing the ball at a position
  • Calculating next position to draw the ball

Below code implements this logic:
function draw()
{
    context.clearRect(0,0,300,300);
    context.beginPath();
    context.fillStyle="green";
    context.arc(x,y,20,0,Math.PI*2,true);
    context.closePath();
    context.fill();  
    
    if(x+xShift > width || x+xShift < 0)
        xShift=0-xShift;
    if(y+yShift > height || y+yShift < 0)
        yShift=0-yShift;
    
    x+=xShift;
    y+=yShift;
}
On page load, we can use setInterval function to call draw function after certain interval.
setInterval(draw,20);



Happy coding!

Wednesday, 28 November 2012

Creating Chess Board Layout Using Pixel Manipulation in HTML5 Canvas


The canvas element in HTML5 can be used to render any graphical content. Shapes, paths, text and even images can be drawn on canvas. Canvas doesn’t support animations, but animations can be created by writing some additional JavaScript code.

Using the pixel manipulation feature of canvas, we can draw images or change colours of existing images. To manipulate pixels, we have to follow the following steps:
  • Create an image data object to draw on the canvas context
  • Loop through each pixel in the area to be drawn
  • Set RGBA values to current position inside the loop
  • Put the image on the canvas context

To draw something specific, we have to logically divide the area to be drawn and manipulate carefully. With this understanding, let’s start drawing a chess board layout.

Create a new HTML page and add a canvas element to the body.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Chess board layout using HTML5 Canvas</title>
</head>
<body>
    <canvas id="chessLayoutCanvas" width="320" height="320" >
        Sorry, your browser doesn't support Canvas!
    </canvas>
</body>
</html>

This is the entire HTML needed for this demo. To draw image on it, we have to write some JavaScript code. Following operations have to be performed inside the JavaScript code:
  • Obtain JavaScript object of the canvas element
  • Get the canvas context
  • Follow steps to draw image

Canvas element will be ready to operate once the entire page is loaded. So, above operations have to be performed once the page is loaded. Following script gets the canvas object and object of the 2-dimensional context:

var canvas = document.getElementById('chessLayoutCanvas');
if(!canvas || !canvas.getContext)
 return;
var context = canvas.getContext('2d');
if(!context || !context.putImageData)
 return;

To draw on the canvas, we have to get an image data object. Canvas context has a function createImageData that returns the object we need, but it is not supported on all browsers. Following snippet shows different ways of obtaining an object using which we can draw some colors on the canvas:
var chessLayoutImage, width, height;
width = canvas.width;
height = canvas.height;
            
if (context.createImageData) {
    chessLayoutImage = context.createImageData(width, height);
}
else if (context.getImageData) {
    chessLayoutImage = context.getImageData(0, 0, width, height);
}
else {
    chessLayoutImage = { 'width': width, 'height': height, 'data': new Array(width * height * 4) };
}

Now that we have the object using which we can achieve what we have to do, let’s think about the logic to draw a chess board layout.

As we all know, a chess board has alternate arrangement of white and black colors. On observing a bit, we can say that the color of last cell on a row is repeated on first cell of next row. Keeping this point in mind and calculating pixels on which we have to draw, I came up with the following logic:
var pixels = chessLayoutImage.data;
var isBlack=true;
for(pixelPosition = 0; pixelCount = pixels.length, pixelPosition < pixelCount ; pixelPosition+=4){
    if(pixelPosition%160==0 && !(pixelPosition%(40*4*320)==0)){
        isBlack= !isBlack;
    }
    if(isBlack){
        pixels[pixelPosition]=0;
        pixels[pixelPosition+1]=0;
        pixels[pixelPosition+2]=0;
        pixels[pixelPosition+3]=255;
    }
}
    
context.putImageData(chessLayoutImage,0,0);
context.strokeStyle='black';
context.strokeRect(0,0,320,320);
context.stroke();

If you observer the above code, I am drawing the black color alone. Place to be filled with white is left as by default the background is white.

After drawing the layout, a black border is drawn around the canvas to show the boundaries of the area.



Happy coding!

Saturday, 17 November 2012

Unit Testing Asynchronous methods using MSTest and XUnit

As we saw in previous posts, writing asynchronous code has become quite easy with .NET framework 4.5. To be able to write well and bug less code in any framework or language, unit tests play a vital role. Unit testing asynchronous code is a bit tricky and it is currently not supported by all unit test frameworks. In this post, we will see how to unit test an asynchronous method using MSTest and the XUnit framework.

Irrespective of the unit testing framework used, the test method written to test the asynchronous method has to follow a set of rules.
  • Test method should be marked as async
  • await keyword should be used while calling the method to be tested
  • Return type of the test method should be Task

I will be using the following asynchronous method for unit testing. It is a very simple method (I have used it in my post on Asynchronizing a C# method using async and await), that divides two numbers with a delay of 2 seconds.
public class ArithemticOperations
{
    public async Task<double> DivideAsync(int first, int second)
    {
        await Task.Delay(2000);
        return (double)second / first;
    }
} 

Unit testing using MSTest

MSTest is the testing framework built into Visual studio. If you are familiar with it, then testing asynchronous method doesn’t require much learning. If you are not already familiar with MSTest, you may go through Unit Testing Framework portion on MSDN.

Testing an asynchronous method is much similar to testing a synchronous method. We just need to follow the rules mentioned above. Following is a test class that tests the divide method created above.
[TestClass]
public class AsyncMethodUnitTests
{
    [TestMethod]
    public async Task DivideAsync_Returns_RightResult()
    {
        int first = 10, second = 20;
        double expected = 2.0;
        ArithemticOperations operations = new ArithemticOperations();
        double actual = await operations.DivideAsync(first, second);
        Assert.AreEqual(actual, expected);
    }
}


Unit testing using XUnit

XUnit is created by James Newkirk and Brad Wilson. It is built to support Test Driven Development with a design goal of simplicity. You may visit the Codeplex site of XUnit to learn more about it.

Testing asynchronous code using XUnit is very straight forward. Following is a test class that tests the divide method:
public class AsyncTests
{
    [Fact]
    public async Task AsyncDivide_Returns_RightResult()
    {
        int first = 10, second = 20;
        double expected = 2;
        ArithemticOperations operations = new ArithemticOperations();
        double actual = await operations.DivideAsync(first, second);
        Assert.Equal(actual, expected);
    }
}

Along with making your code run better by applying asynchronous strategies, you can unit test and even test drive them.

Happy coding!

Asynchronous controller actions in ASP.NET MVC 4

In this post, let’s continue our discussion on asynchronous programming in .NET 4.5 with ASP.NET MVC4. We will see how to create asynchronous controller actions in ASP.NET MVC 4.

 As in case of pages and handlers ASP.NET web forms, it was not easy to create asynchronous controller actions in ASP.NET MVC till MVC 3. We had to derive the controller class from AsyncController and create async and completed methods for the controller action that performs asynchronous task. This is quite a bit of work to perform.

As ASP.NET MVC 4 runs on top of .NET framework 4.5, we can use the magical async and await keywords to simplify this process. Using these keywords, we can easily create asynchronous controller actions just like we created methods in earlier posts. Following is a sample implementation of a controller action method:

public class HomeController : Controller
{
    public async Task<ActionResult> Index()
    {
        DataServiceClient client = new DataServiceClient();
        var cities = await client.GetCitiesAsync();
        return View(cities);
    }
}

 In the above code, we are calling a WCF service asynchronously. As a method marked as async must return a Task, the return type is modified to Task<ActionResult>.

Happy coding!

Wednesday, 14 November 2012

Asynchronous HttpHandlers in ASP.NET 4.5

HttpHandlers are responsible to handle all types of HTTP requests that an ASP.NET web server receives. Page is also an HttpHandler, as it is derived from IHttpHandler interface.

Need of creating an HttpHandler may arise when we want to have more control over the way a request is handled. There can be scenarios where we have to generate some content dynamically like a captcha image to show on a page or generate some file that the user will download. In such cases, HttpHandler is the choice we stop at.

The HttpHandler may perform operations like fetching data from a remote location (like service calls, heavy DB queries) and some I/O operations on the disc. As sever would take considerable amount of time to complete such requests, it is better to perform them asynchronously.

To create an asynchronous HttpHandler in older versions of ASP.NET, the handler class has to be derived from IHttpAsyncHandler and implement its members. In ASP.NET 4.5, this process is simplified with the abstract class HttpTaskAsyncHandler. It has an abstract method ProcessRequestAsync, returning a Task. We can use the magical async and await keywords inside this method.

Following is a sample implementation an HttpHandler derived from HttpTaskAsyncHandler:

public class AsyncHandler : HttpTaskAsyncHandler
{
    public override async Task ProcessRequestAsync(HttpContext context)
    {
        //Calling a service to fetch data
        var client = new DataServiceClient();
        var getCitiesTask = client.GetCitiesAsync();

        //Setting folder path and file name
        string folderPath = context.Server.MapPath("Downloadables");
        string fileName = "cities.xlsx";

        //Asynchronously calling a method to store data obtained from service in an excel file
        await Task.Factory.StartNew(() => FillDataIntoExcel(getCitiesTask.Result, folderPath, fileName));

        //Sending the excel file to user's system
        context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        context.Response.WriteFile(folderPath + "\\" + fileName);
    }
}

You can download the complete source code of the handler here: Download Source. The sample application also contains implementation of an asynchronous web form.

Happy coding!

Sunday, 11 November 2012

Asynchronous pages in ASP.NET 4.5

In my previous post, we discussed the importance of asynchrony in ASP.NET applications. Before that, I blogged about using asynchrony in C# 5 and calling WCF services asynchronously using features in C# 5. In this post, we will learn how to create an ASP.NET web forms page that performs some asynchronous operations.

To make a page asynchronous in earlier versions of ASP.NET, the page has to implement the interface IHttpAsyncHandler and define concrete definitions to all the methods declared in the interface. This takes considerable amount of time and effort to make the page asynchronous.

In ASP.NET 4.5, we can turn the execution of any operation asynchronous by using async and await keywords. Any new page added to an ASP.NET application is considered synchronous by default. We can change this by setting value of Async property of the Page directive to true. Once this property is set, we can use async and await keywords in any method in the code behind file.

<%@ Page Language="C#" AutoEventWireup="true" Async="true" CodeBehind="Default.aspx.cs" Inherits="Async.Default" %>

This is because, performing asynchronous operations at wrong time may lead to some dangerous conditions on the server. By setting the Async attribute of the page, we are telling the server that, the current page is a safe place to perform async operations. Following is a sample page load event handler that calls a WCF service asynchronously and binds data to a GridView:
protected async void Page_Load(object sender, EventArgs e)
{
    var client = new DataServiceClient();
    var gettingCities = await client.GetCitiesAsync();
    gvCities.DataSource = gettingCities;
    gvCities.DataBind()                                                  
}

Following are the set of steps performed when ASP.NET detects the await keyword in the above event handler:
  • Continues executing other synchronous tasks of the life cycle event
  • Once the above step is finished, the underlying synchronization context fires up an event saying that an async operation is pending
  • ASP.NET waits asynchronously till the pending task is completed and then it continues executing the rest of the statements
  • With above step, the life cycle (page load in this case) event is over. The control goes ahead to the next life cycle event


There is another way to achieve this. It is shown in the following snippet:
protected void Page_Load(object sender, EventArgs e)
{
    RegisterAsyncTask(new PageAsyncTask(async () =>
    {
        var client = new DataServiceClient();
        var gettingCities = await client.GetCitiesAsync();
        gvCities.DataSource = gettingCities;
        gvCities.DataBind();
    }));                                                                                    
}

The advantage of performing async operation this way over what we did earlier is that, it registers an asynchronous handler with the page and now the execution is not dependent on the synchronization context. Execution of the statements in the PageAsyncTask passed in is not dependent on page the page life cycle event. So, ASP.NET will not wait asynchronously after executing rest of the logic in the life cycle event. It would rather continue execution with the next life cycle event handlers. Statements in the registered task are performed whenever the dependent operation is finished.

Note that, we used the async keyword with a lambda expression. It is legal in .NET 4.5, because lambda is meant to create a single cast delegate with an anonymous method. To make the method executable asynchronously, we can use async and await with lambda.

Further learning: Async in ASP.NET talk from AspConf 2012

Happy coding!