Preface
In C #5.0, The async await keyword is added to support asynchronous programming. Before talking about these two keywords, I will summarize the common asynchronous programming models in. NET.
Asynchronous programming has always been a complicated problem, among them, data synchronization between multiple threads, obtaining progress, cancelling, obtaining results, not affecting the operations of the main thread, and not affecting each other among multiple tasks are required, therefore, we need to design a programming model to deal with such problems.
Three asynchronous programming modes supported starting from. NET 4.5:
Event-based Asynchronous Pattern)
Asynchronous Programming Model (APE, Asynchronous Programming Model)
Task-based programming model (TAP, Task-based Asynchronous Pattern)
Currently, the new version of. NET prefers to use the TAP Method for asynchronous programming. The asynchronous operations in WINRT only involve the TAP, and The async await keyword only supports the TAP programming model.
Event-based asynchronous mode-EAP
The codes in the EAP programming mode have the following features:
There will be one or more methods named "[method name] Async. These methods may create images of the synchronous version, which will perform the same operation on the current thread.
This class may also have a "[method name] Completed" event to listen to the results of asynchronous methods.
It may have a "[method name] AsyncCancel" (or just CancelAsync) method to cancel ongoing asynchronous operations.
The following is an example of a class declaration that complies with this pattern.Copy codeThe Code is as follows: public class AsyncExample
{
// Synchronous methods.
Public int Method1 (string param );
Public void Method2 (double param );
// Asynchronous methods.
Public void Method1Async (string param );
Public void Method1Async (string param, object userState );
Public event Method1CompletedEventHandler Method1Completed;
Public void Method2Async (double param );
Public void Method2Async (double param, object userState );
Public event Method2CompletedEventHandler Method2Completed;
Public void CancelAsync (object userState );
Public bool IsBusy {get ;}
// Class implementation not shown.
}
Here, the fictitious AsyncExample class has two methods, both supporting synchronous and asynchronous calls. Synchronous Overloading is similar to method calling. They perform operations on the calling thread. If the operation is time-consuming, the return of the call may be significantly delayed. Asynchronous overload will start the operation on another thread, and then return immediately, allowing the operation to be executed "in the background" while the calling thread continues to execute.
System. Net. WebClient itself has many EAP examples. Taking its DownloadString as an exampleDownloadString-related methods include::
DownloadString: synchronous method for downloading string resources. This method blocks the current thread.
DownloadStringAsync: Method for downloading string resources in EAP asynchronous programming mode. This method does not block the current thread.
DownloadStringCompleted: responds to events completed during asynchronous download.
DownloadProgressChanged: Changes in degrees in response to asynchronous downloads.
Call model example::Copy codeThe Code is as follows: using System;
Using System. Collections. Generic;
Using System. Linq;
Using System. Text;
Using System. Net;
Namespace AsyncTest1.EAP
{
Public class EAPRunTest1
{
Public static void AsyncRun (){
Utility. Log ("AsyncRun: start ");
// Test URL
String url = "http://sports.163.com/nba ";
Using (WebClient webClient = new WebClient ()){
// Monitor the download progress
WebClient. DownloadProgressChanged + = new DownloadProgressChangedEventHandler (webClient_DownloadProgressChanged );
// Monitor the completion status
WebClient. DownloadStringCompleted + = new DownloadStringCompletedEventHandler (webClient_DownloadStringCompleted );
WebClient. DownloadStringAsync (new Uri (url ));
Utility. Log ("AsyncRun: download_start ");
}
}
Static void webClient_DownloadStringCompleted (object sender, DownloadStringCompletedEventArgs e)
{
String log = "AsyncRun: download_completed ";
Log + = "| cancel =" + e. Cancelled. ToString ();
If (e. Error! = Null)
{
// If an exception occurs, an exception is recorded.
Log + = "| error =" + e. Error. Message;
}
Else {
// If no exception occurs, the result is recorded.
Log + = "| result_size =" + Utility. GetStrLen (e. Result );
}
Utility. Log (log );
}
Static void webClient_DownloadProgressChanged (object sender, DownloadProgressChangedEventArgs e)
{
Utility. Log ("AsyncRun: download_progress | percent =" + e. ProgressPercentage. ToString ());
}
}
}
Running result:
2012-12-28 00: 39: 39: 621 AsyncRun: start
00: 39: 40: 377 AsyncRun: download_start
00: 39: 40: 903 AsyncRun: download_progress | percent = 1
00: 39: 40: 933 AsyncRun: download_progress | percent = 3
00: 39: 40: 933 AsyncRun: download_progress | percent = 5
00: 39: 40: 934 AsyncRun: download_progress | percent = 5
00: 39: 40: 975 AsyncRun: download_progress | percent = 9
2012-12-28 00: 39: 41: 068 AsyncRun: download_progress | percent = 21
00: 39: 41: 131 AsyncRun: download_progress | percent = 29
00: 39: 41: 182 AsyncRun: download_progress | percent = 37
00: 39: 41: 298 AsyncRun: download_progress | percent = 50
00: 39: 41: 354 AsyncRun: download_progress | percent = 58
00: 39: 41: 447 AsyncRun: download_progress | percent = 74
00: 39: 41: 489 AsyncRun: download_progress | percent = 82
00: 39: 41: 582 AsyncRun: download_progress | percent = 100
00: 39: 41: 582 AsyncRun: download_progress | percent = 100
00: 39: 41: 614 AsyncRun: download_completed | cancel = False | result_size = 205568