Basic operations for async and await

Source: Internet
Author: User

If there are several Uris that need to get the sum of the length of all the contents of these Uris, what would you do?

It is easy to use WebClient to get the content length of the uri one by one and accumulate it.

That is to say, if there are five Uris, the request time is: 1 s 2 s 3 s 4S 5 s.

The required time is: 1 + 2 + 3 + 4 + 5 = (6*5)/2 = 15.

If parallel computing is used, the result may be as follows:

The total time is 5 s.

To demonstrate the effect, the following three pages are required:

The code for Page_load of SlowPage is as follows:

Copy codeThe Code is as follows: protected void Page_Load (object sender, EventArgs e)
{
Thread. Sleep (5000 );
}

For the Page_load event of VerySlowPage, Thread. Sleep (10000 );

Create the console program CAStudy:
First, create a class AsyncDemo:
The code for synchronously obtaining the URL content length is as follows:Copy codeThe Code is as follows: public class AsyncDemo
{
Public int SumPageSizes (IList <Uri> uris)
{
Int total = 0;
Foreach (var uri in uris)
{
Console. WriteLine ("Thread {0}: Found {1} bytes... {2 }",
Thread. CurrentThread. ManagedThreadId, total, DateTime. Now );
Var data = new WebClient (). DownloadData (uri );
Total + = data. Length;
}
Console. WriteLine ("{0}: Found {1} bytes total {2 }",
Thread. CurrentThread. ManagedThreadId, total, DateTime. Now );
Return total;
}
}

Here, the SumPageSizes method downloads data one by one through a foreach loop.

The Main function is as follows:Copy codeThe Code is as follows: public static void Main ()
{
List <Uri> uris = new List <Uri> ();

Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/QuickPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/SlowPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/VerySlowPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/QuickPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/SlowPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/VerySlowPage. aspx "));
AsyncDemo asyncDemo = new AsyncDemo ();
Int totalSize = asyncDemo. SumPageSizes (uris );
}

The Main function is to construct a Uri, and then call the SumPageSizes method of AsyncDemo to obtain the total length of all the Uris.

The result is as follows:

We can see that the time is 0 s, 5S, 10 s, 0 s, 5S, 10 s. So the total length is(0 + 5 + 10) * 2 = 30.

It can be seen that the speed is very slow. If a webpage gets stuck, it will be terrible.

The following shows how to use async and await:

Step 1: Upgrade VS2010 to VS2010 sp1.

Step 2: Download Async CTP for Installation

Step 3: Add AsyncCTPLibrary reference to the application, as shown below:

OK. Modify the above SumPageSizes method as follows:

Copy codeThe Code is as follows: public async Task <int> SumPageSizesAsync2 (IList <Uri> uris)
{
Var tasks = uris. Select (uri => new WebClient (). DownloadDataTaskAsync (uri ));
Var data = await TaskEx. WhenAll (tasks );
Return await TaskEx. Run () =>
{
Return data. Sum (s => s. Length );
});
}

In AsyncCTPLibrary. dll, Microsoft provides extensions for some classes as follows:

The extension of WebClient is as follows:

We can see that a XXXTaskAsync extension method is added for each Download.

All returned results are tasks,

Why are all tasks?Because await can only be a wait Task, and await can only be used in async marking methods,

The async keyword indicates that this is an Asynchronous Method.

First sentence:

Public async Task <int> SumPageSizesAsync (IList <Uri> uris)

Because we declare an asynchronous method, we need to use the async keyword. The result returned by the SumPageSizesAsync method is of the int type, so the Task <int> is returned.

Second sentence:

IEnumerable <Task <Byte []> tasks = uris. Select (uri => new WebClient (). DownloadDataTaskAsync (uri ));

Obtains all tasks returned by DownloadDataTaskAsync.

Third sentence:

Byte [] [] data = await TaskEx. WhenAll (tasks );

The second sentence returns the IEnumerable <Task <Byte []> type, that is, the Task of one Task <Byte []>, the WhenAll method of TaskEx can be used to convert these tasks into a <Byte [] []> Task.

When the await keyword is used, the <Byte [] []> method of the Task needs to wait, and the Byte [] [] is returned after the Task ends.

Fourth sentence:

Return await TaskEx. Run <int> () =>

{

Return data. Sum (s => s. Length );

});

When TaskEx. Run is returned, the data returned in the third sentence is used to perform the Sum operation on the data in Byte [] [], and an object of the Task <int> is returned. If await is not used:

Because the async keyword represents an Asynchronous Method and the result returned by this Asynchronous Method is int, you need to use the await keyword again:

Return await TaskEx. Run <int> () =>
{
Return data. Sum (s => s. Length );
});

Modify the Main Code as follows:

Copy codeThe Code is as follows: public static void Main ()
{
List <Uri> uris = new List <Uri> ();

Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/QuickPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/SlowPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/VerySlowPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/QuickPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/SlowPage. aspx "));
Uris. Add (new Uri ("http: // localhost: 57815/AsyncTestPages/VerySlowPage. aspx "));
AsyncDemo asyncDemo = new AsyncDemo ();
Console. WriteLine (DateTime. Now );
Int totalSize = asyncDemo. SumPageSizesAsync (uris). Result;
Console. WriteLine ("TotalSize: {0}, Finished", totalSize );
Console. WriteLine (DateTime. Now );
}

The running result is as follows:

We can see that 16 seconds is used, which is roughly equal to the theoretical value of 15.

Some colleagues say that it is very troublesome !, Indeed, I also feel very troublesome, but it is not as fast as ThreadPool. However, async and await mainly do not solve such problems. What it solves is asynchronous synchronization, that is to say, in some asynchronous operations, synchronous processing is required, for example, in Silverlight,

Asynchronous acquisition of A-> asynchronous acquisition of B-> asynchronous acquisition of C ..

If you use the traditional method, you need:

Copy codeThe Code is as follows: WebClient webClient = new WebClient ();
WebClient. DownloadDataCompleted + = (s, e) =>
{
// Use object A to do something.
WebClient webClient2 = new WebClient ();
WebClient2.DownloadDataCompleted + = (s2, e2) =>
{
// Use object B to do something.
};
WebClient2.DownloadDataAsync (new Uri ("B's address "));
};
WebClient. DownloadDataAsync (new Uri ("A's address "));

Of course, the most ugly version is demonstrated here. Smart users can use Enumerable to simplify asynchronous operations.
If you use async and await, you can change it:Copy codeThe Code is as follows: public async Task <int> SumPageSizesAsync3 (IList <Uri> uris)
{
Int total = 0;
Foreach (var uri in uris)
{
WebClient webClient = new WebClient ();
Var data = await webClient. DownloadDataTaskAsync (uri );
Total + = data. Length;
}
Return total;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.