Wednesday, December 15, 2010

[Visual C# 5.0] How-To: Asynchronous Programming (1/2)

Most of todays applications are developed to work sequentially. Developers are quite used to the sequential approach since it is easy to be implemented and easy to understand. But it makes no sense to always respond to development problems by using this approach. Furthermore, the user has to wait until each of the sequential operations have finished until the next ones can be processed. Sometimes this means waiting for a result on the user side – and users don’t like to wait!

There are multiple reasons why developers may want to structure their code in an asynchronous way. Sometimes it is to allow a better user experience (not waiting anymore) or better perceived performances and sometimes it is due to technical restrictions (such as for Silverlight for example).

The current version of C# 4.0 integrates everything necessary to implement asynchronous code manually. But as you might already know asynchronous code quickly gets unreadable and hard to maintain. But this is going to change in the future version of C# which will include a new abstraction layer that will greatly ease asynchronous programming.

I will take the example of calculating factorials in a Command Line project during these blog posts. But you may take any other code that you want to render asynchronous.

In the first step I am going to write the synchronous C# 4.0 version of the code. I will then show you how you could modify your code in C# 4.0 and C# 5.0 to make the same code asynchronous.

Factorials Synchronous Code in C# 4.0

The main function in the example project contains the user input code as well as the synchronous function call. I did not add any error nor exception handling for simplicity purposes.


The synchronous function contains the main application logic: factorials calculated via a for loop (no recursion for simplicity purposes). I also added a Thread delay to simulate calculation time.


Each step is marked in the logical order they are executed:

  • Step1: Enter User Data
  • Step2: Result of the calculation
  • Step2: Exiting the function call

If we start this application and enter a valid value you can see that there will be a certain delay until you will get the output for Step2 and Step3. This is completely normal and due to the synchronous calling.


So the processing is blocked until all operations in the synchronous order are completely finished. If you don’t like this behavior then look carefully at the next sections!

Factorials Asynchronous Code in C# 4.0

The next step consists of extending the existing project by adding some new functions and modifying the existing main function. In the main function a new asynchronous function call is added.


To render the code asynchronous we need to add a delegate which will be used to decouple the function call. In my example I also use a CallBack function and a AsyncOperation. You could do this differently but I choose this approach to show how complex it can get when migrating you code to be asynchronous in the current version of C#.


The function with the application logic is the same as in the synchronous version of the code. The only difference will be that it won’t be called directly but by using the delegate that was defined above.


The callback function contains the business logic that is applied when the asynchronous call is completed.


I added also some logic to be able to get informed via an event when the CallBack function has finished (not used anywhere in my code however). But you might need to be informed when the asynchronous operation has been terminated.


When executing the application the part that handles the asynchronous call achieves that the factorial calculation is done in the background and the result is displayed when it is finished.

Each step is marked in the logical order they are executed :

  • Step1: Enter User Data
  • Step2: Result of the calculation
  • Step3: Exiting the function call
  • Step4: Do some other stuff

When starting the application and entering a valid value you see that there is no more delay getting the output for Step3 and Step4. The application is not blocked anymore by the processing which is done in Step2. When the asynchronous processing in Step2 is finished the result is written to the Command Line. That is why the execution order is different from the logical order.



No comments: