Asynchronous Programming in. Net 5 Cole Durdan Department of Computer Science University of Wisconsin-Platteville



Download 27.87 Kb.
Date09.08.2017
Size27.87 Kb.
#29156
Asynchronous Programming in .NET 4.5

Cole Durdan

Department of Computer Science

University of Wisconsin-Platteville

durdanc@uwplatt.edu



Abstract
Asynchronous programming can be a powerful tool, and yet with traditional methods it can be hard to implement, debug, and maintain. With the use of asynchronous programming, application performance and responsiveness can be greatly enhanced. User interfaces can remain responsive while expensive computational operations are performed. In the past, there were a lot of situations a developer had to be aware of while writing an asynchronous program and there was a lot of added code to the mix. What .NET framework 4.5 enables you to do is create asynchronous code while the compiler does the difficult work for you. The code you write resembles synchronous code and it is much more readable than previous solutions. Understanding asynchronous programming and using the new tools available in Visual Studio 2012 will allow you to develop more powerful programs.

Introduction
When Visual Studio 2012 was released in August 2012 Microsoft also introduced the new .NET Framework 4.5. This new framework included a whole new concept of asynchronous programing. If you are unfamiliar with the term you may be asking yourself, “What does asynchronous programming mean?” The term parallel programming is also used and it essentially means that multiple processes can happen at the same time instead of one by one. Figure 1 shows a visual representation of Synchronous vs. Asynchronous execution with respect to time. The different colored sections could represent separate functions in a program.http://cdn.marketingtechblog.com/wp-content/uploads/2012/09/asynchronous-640x306.png

Figure 1: Synchronous vs. Asynchronous Comparison

If you are familiar with the term you might commonly associate it with the use of multi-threading. Actually, asynchronous programming does not necessarily mean multi-threaded code. An asynchronous event is an event that occurs independently from the main program flow. An asynchronous method is executed in a manner that does not block the calling function, allowing that function to continue functioning. This can be difficult to comprehend at first because a thread can only do one thing at a time. Writing asynchronous code that only uses one thread means that multiple processes are occurring on one thread at the same time. Control of the thread between the processes needs to be handled in the most efficient manner.
Writing a multi-threaded program can be difficult to write and it introduces many problems that you will have to face. If you are going to write a multi-threaded program you need to be aware of basic threading concepts such as the risk of starvation, locks, deadlocks, and race conditions. This is why it is very important to understand when you should be using multiple threads.
Writing this asynchronous code can be very simple too. The programming languages C# and VB.NET use two new keywords the framework introduced, “async” and “await”. With these new keywords you are able to write a program like you are used to synchronously, and with a few minor modifications you can turn it into an asynchronous program. The main application of using asynchronous code is to keep the thread that the user interface (UI) is on from being blocked.
Imagine your program has some background tasks working and the UI is frozen because they have control of the main thread. Your user could think that the program has crashed and is nonresponsive when in fact it is still working. By implementing the two new keywords on your program you could fix this problem in a matter of minutes.
When to Use Single Thread or Multi-Thread

Parallel programing is important to advance the speed of future programs. In the past, when you wanted a program to execute faster you could just wait six months and a new processor would come out that would be twice as fast as its predecessor. This was due to more transistors and a higher clock speed, but somewhere around the year of 2004 a physical limit to clock speed had been reached. Newer processors no longer have faster clock speeds. Now, the only way to speed up applications from here is to take advantage of multi core CPUs.


The main benefit of multi-threading is that threads are able to work on different cores of the CPU. Therefore, they can both handle computations at the same time. The essence of a process that you would want to put on a separate thread is one that utilizes the CPU. Large mathematical computations and rendering are examples of CPU intensive processes that you would want to do with multiple threads.
The main objective in writing parallel code is to not block the thread that the UI is on. There are many processes in programming that involve simply waiting for responses. For example, web requests to websites do not rely on the CPU they simply take time because they are waiting for the collection of data to return. Other types of processes that are not CPU dependent yet still involve waiting include I/O bound procedures, working with files, working with images, database requests, and working with sockets. These are all examples where multiple threads are unnecessary and simply not worth the added risks and confusion.
When Should Asynchronous Programming Be Used
Why would you want to write parallel code using a single thread? This question is raised a lot when first explaining this topic. Every programmer does, or should, know that multi-threading a program is how you increase speed and responsiveness of a program. But what if the “costly” procedures of the program do not carry a high computational burden? There are times where the operations that take the most time in a program are simply just waiting for a response from an external resource.
The most prominent example of this is an application that makes a web request. A web request does not put a large stress on the CPU, but it does take time to get the response. Say you have a program that is making multiple web requests at the same time. With a synchronous program you would have to wait to receive the answer from each request before moving onto the next one. Because of this the application could become unresponsive due to waiting for these responses. This is where the new asynchronous programming comes into play. Using a separate thread to make the web requests would just introduce all of the problems that come with multithreading such as race conditions and a lot of overhead code. Also, it would not run any faster than just using one thread because the responses are not dependent on the CPU. Therefore, using the new asynchronous approach would very simply solve this nonresponsive UI problem.
Some other areas that the single thread asynchronous model is applicable are database requests, working with files, working with images, and working with sockets. The main highlight of when you should use this new functionality is when you are working with user interfaces that you want to be responsive. Keeping the user of your programs informed of what is happening and happy is the main goal with parallel programming. With the new framework you can achieve this without spending the extra time to multi-thread your program.
Previous Asynchronous Patterns
Before .NET 4.5 there were two standard models that were used to create Asynchronous Programs. These included the Asynchronous Programming Model (APM) and the Event based Asynchronous Pattern (EAP).
APM code was implemented using two methods named BeginMethodName and EndMethodName. The .NET framework has many classes that support the APM model using these Begin and End methods. For example, to asynchronously read bytes from a file you can use the methods BeginRead() and EndRead() of the FileStream class. When the Begin operation is called it will create a new thread that the actual reading will be done on leaving the calling thread free to carry on with its business. For every Begin call there needs to be a matching End call to get the results.
Event based Asynchronous Programming relies on assigning delegates to event handlers that will be invoked when an event is triggered. With EAP you will see asynchronous methods with naming conventions like MethodNameAsynch() and a corresponding event for when the asynchronous method completes, MethodNameCompleted(). This is the most basic form of EAP. Some asynchronous classes could be more complex and involve more than one MethodNameAsync(). For example, if an asynchronous operation needs to be canceled there could be a method named CancelAsync() that would submit a request for the operation to quit and then raise the MethodNameCompleted() event handler.
The pattern that is now used in the new framework is named the Task-based Asynchronous Pattern (TAP). It relies on the Task Parallel Library (TPL) and the System.Threading.Task namespace that was introduced in .NET Framework 4.
Tasked Based Asynchronous Programming
The asynchronous programming model that .NET 4.5 uses is named the Task-based Asynchronous Pattern (TAP). It is based on types from the namespace System.Threading.Task realeased in .NET 4 and supported in .NET 4.5. These types of Task or Task represent ongoing asynchronous operations. TAP is the new standard for writing asynchronous code in .NET. The reason TAP makes asynchronous programming so simple is the ability to write code as if it were synchronous. In fact, code can be written synchronously first and easily transformed into asynchronous code by using the new keywords “async” and “await”. TAP differs from the previous EAP and APM methods in the fact that asynchronous operations are handled by one method. Event handlers from the EAP model and End methods from the APM model are no longer needed to handle the asynchronous procedure.
System.Threading.Tasks
This namespace contains the types that are used in the new asynchronous programing model. Task is an implementation to IAsyncResult, which is an interface which represents the status of an asynchronous operation. Previously, the IAsyncResult interface was used by the APM for its design pattern with the Begin and End methods. The two most prominent types in this namespace are type Task and Task. With TAP all asynchronous methods are going to return one of these two types. What the Task class represents is an ongoing operation. Therefore, in comparison to synchronous code a void function is going to be replaced by a function of type Task. A value returning function is going to return type Task where TResult is the original type of value. For example, a value returning function of type int will instead return Task. A Task object has the ability to be waited on and cancelled. Also, creating and scheduling Tasks on separate threads can be easily done with the help of the System.Threading.Task.TaskFactory class.
Task Parallel Library
The new TAP is built on top of the Task Parallel Library (TPL) which was introduced in .NET 4. The TPL is a set of public types and APIs from the System.Threading.Tasks namespace. The TPL was created to greatly simplify adding parallelism and concurrency to applications. The TPL is used by the new .NET framework to handle the partitioning of work, scheduling of threads on the ThreadPool, cancellation support, state management, and other low-level details. When you use the two new keywords you are having a lot of work done for you. The framework now has the compiler dealing with all the scheduling tasks of asynchronous programs for you and thus greatly simplifying your code.
Keywords
Microsoft has created a naming convention to go along with TAP. When writing an asynchronous method the convention is that the method name will end with the word async.
Ex. MethodNameAsync.
Technically, you do not need to do this as it serves no functional purpose but rather just stands as a conventional guideline. The following two keywords, async and await, are however needed to write an asynchronous method with TAP.
Async
Each declaration of an asynchronous method needs to be marked with either the modifier Async or async. This keyword will sit before the return type of the method. A method marked with async can be awaited by methods that call it.
Ex. Async Task MethodNameAsync()
Await
The marked async method will then be allowed to use the await operator to mark points of suspension. The await operator tells the compiler that it cannot pass this part of the code until the task it awaits is completed. When await operators are reached the control will be given back to the caller of the method. An async method usually contains one or more await operators but a compiler error does not occur at their absence. An absence of await operators in an async method will simply result in a compiler warning.
Flow of Control Explained
If you are unfamiliar with asynchronous programming first implementing TAP can be confusing. It is difficult to understand what will have control of the thread until you start experimenting with code and seeing it in action. To help you understand what is actually happening when a method with the new keywords is called I am going to walk you through an example and explain what happens at each step. Refer to Figure 2 while reading the following steps.
Step 1
The method AccessTheWebAsync() gets called from an event handler of a StartButton being clicked.
Step 2
A new HTTP client is created and the method GetStringAsync() is called with Microsoft’s website as the parameter. What this method does is send a GET request to the specified Uri and return the response body as a string.
Step 3
A blocking activity occurs in the method and GetStringAsync() returns a Task of string representing an ongoing process of the call to the method. This task could be seen as a promise to deliver a string. The method was most likely blocked by having to wait for the website to download. So, in order to keep the thread active it returned the task.
Step 4
The method AccessTheWebAsync() carries on and calls the method DoIndependentWork(). This will happen synchronously while the getStringTask is still waiting for its string.
Step 5
The method DoIndependentWork() writes some results to a text box and then returns control back to the method AccessTheWebAsync().
Step 6
Here the method AccessTheWebAsync() cannot go any further without the string result from the getStringTask. So the await operator is used which hands control of the thread back to the calling function. A Task of integer is returned to the caller. This task represents the ongoing procedure of returning an integer the size of the response body of Microsoft’s page.
It is noteworthy to say here that if getStringTask is complete before the await operator is called here the method AccessTheWebAsync() would carry on like a synchronous method instead of yielding control back to the calling function.

trace an async program

Figure 2: Example of Asynchronous Method


Step 7
GetStringAsync() completes and instead of returning a result the string is stored in the Task getStringTask. When using TAP the compiler creates a type of event handler that is set up in the background that will trigger this. So if the program is sitting idle when this happens AccessTheWebAsync() will regain control and set the variable urlContents to the string stored in getStringTask.
Step 8
The length of urlContents will then be stored in the Task object that was set when calling AccessTheWebAsync(). Then, whenever the event handler calls await on that task it will either hand control back to the calling UI or extract the int value representing the size of the contents of Microsoft’s website.
It may take you a couple of times to read through these steps to understand what is going on. This example uses multiple await operators and can be confusing at first. The main thing to understand from this is that when an await operator is reached control is then handed back to the calling function. This is done to ultimately give back the control of the thread to the UI so the UI does not freeze up as it is waiting for long operations to be handled. Specifically, during step six when the await is reached in AccessTheWebAsync() control is handed back to the event handler of the Start Button being clicked. This event handler method (StartButton_Click) is waiting for the integer representing the size of the contents of Microsoft’s homepage. When this number is needed the Task can be awaited returning control back to the UI. The UI will then again be responsive and not frozen while these asynchronous operations are waiting to finish. When the tasks finish in the background event handlers that the compiler made will fire off and the rest of the code after the “await” operators will be finished.
The reason most people get confused here is because they don’t understand when control will be handed back to the await operator to extract the value from the task and finish the rest of the asynchronous method. The way this happens is that when the code is compiled an event handler very similar to the ones used in EAP is created. When the task is finished the event is raised so when the thread goes idle the control will be handed back to the asynchronous method to complete. This is how TAP achieves such a simple way to write asynchronous code. The new framework handles all of the difficult work for you.
There are limitations to having the framework do all of this work for you, of course. You are limited to customization of how events are scheduled. There may be times when you have a unique program that needs to handle a certain condition in a certain way. Reading and learning more about the Task class and Task Parallel Library can be beneficial to understand more about how these operations are ordered.
Conclusion
The use of asynchronous programming is a valuable tool when optimizing programs for performance. Especially if that program has a user interface that you would like to keep responsive. Having an interface that does not constantly freeze up is an important issue and keeps users happy. With Microsoft’s new framework writing asynchronous code has never been easier. That asynchronous code can either be on a single thread or multiple threads thanks to the implementation of the Task class. You can also be less wary when choosing to use multi-threading. Now all of the frustrating work can be done by the compiler thanks to the use of the Task Parallel Library. Asynchronous programs on a single thread avoid the risk of starvation, locks, deadlocks, and race conditions. You now know when it is appropriate to write single threaded parallel code as well. Creating asynchronous code on a single thread is a fairly new idea. It greatly increases the process of creating asynchronous code and is applicable to many common types of programs. These techniques can be very useful when writing applications that make web or database requests. This type of asynchronous programming is great to use with ASP.NET as well. Websites very commonly use all of the cases where only a single thread is needed. With the use of asynchronous programming you will be able to create responsive and efficient programs.

References
[1] Microsoft. Asynchronous Programming with Async and Await (C# and Visual Basic). Retrieved from http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

[2] Brandon Bray 3 Apr 2012 10:17 AM. Async in 4.5: Worth the Await. Retrieved From http://blogs.msdn.com/b/dotnet/archive/2012/04/03/async-in-4-5-worth-the-await.aspx

[3] Rick Anderson June 6, 2012. Using Asynchronous Methods in ASP.NET 4.5 Retrieved From http://www.asp.net/web-forms/tutorials/aspnet-45/using-asynchronous-methods-in-aspnet-45

[4] DotNetPearls. C# Async, Await. Retrieved From http://www.dotnetperls.com/async



[5] Assil, 14 May 2013. Asynchronous Programming in C# 5.0 using async and await. Retrieved From http://www.codeproject.com/Tips/591586/Asynchronous-Programming-in-Csharp-5-0-using-async


Download 27.87 Kb.

Share with your friends:




The database is protected by copyright ©ininet.org 2024
send message

    Main page