Synchronous VS asynchronous, synchronous vs asynchronous

Source: Internet
Author: User

Synchronous VS asynchronous, synchronous vs asynchronous
Synchronous request Resource

Request a page on msdn to calculate the page size

static void Main(string[] args){    string url = "https://docs.microsoft.com/zh-cn/dotnet/core/api/system";    try    {        WebRequest request = WebRequest.Create(url);        WebResponse response = request.GetResponse();        using (var reader = new StreamReader(response.GetResponseStream()))        {            string text = reader.ReadToEnd();            Console.WriteLine(FormatBytes(text.Length));        }    }    catch (WebException e)    {    }    catch (IOException e)    {    }    catch (NotSupportedException e)    {    }}static string FormatBytes(long bytes){    string[] magnitudes = new string[] { "GB", "MB", "KB", "Bytes" };    long max = (long)Math.Pow(1024, magnitudes.Length);    var t1 = magnitudes.FirstOrDefault(magnitude => bytes > (max /= 1024)) ?? "0 Bytes";    var t2 = ((decimal)bytes / (decimal)max);    return string.Format("{1:##.##} {0}", t1, t2).Trim();}

Ctrl + F5 output

After two flashes

Requests to resources are synchronized here. The easy-to-understand point is the execution of one step and one step. If any step takes a long time, it will block the context thread (the main thread here)

Use C #5.0 to request resources Asynchronously
Static void Main (string [] args) {string url = "https://docs.microsoft.com/zh-cn/dotnet/core/api/system"; Task task = WriteWebRequestSizeAsync (url); while (! Task. wait (100) {Console. write (". ") ;}} static async Task WriteWebRequestSizeAsync (string url) {try {WebRequest request = WebRequest. create (url); WebResponse response = await request. getResponseAsync (); using (var reader = new StreamReader (response. getResponseStream () {string text = await reader. readToEndAsync (); Console. writeLine (FormatBytes (text. length) ;}} catch (WebException) {}// some catch blocks are omitted}

 

This method has long been familiar with MVC, but the principle is not very clear. I only know that this will not block the UI. The async method will create a new thread for execution, and await will block the context thread, it's a terrible time bomb!

Asynchronous call of TPL
Static void Main (string [] args) {string url =" https://docs.microsoft.com/zh-cn/dotnet/core/api/system "; Task task = WriteWebRequestSizeAsync (url); try {while (! Task. wait (100) {Console. write (". ") ;}} catch (aggresponexception excetion) {excetion = excetion. flatten (); try {excetion. handle (innerExcetion =>{ ExceptionDispatchInfo. capture (excetion. innerException ). throw (); return true;});} catch (WebException ex) {}// some catch blocks are omitted} static Task WriteWebRequestSizeAsync (string url) {StreamReader reader = null; webRequest request = WebRequest. create (url ); Task task = request. getResponseAsync (). continueWith (antecedent => {WebResponse response = antecedent. result; reader = new StreamReader (response. getResponseStream (); return reader. readToEndAsync ();}). unwrap (). continueWith (antecedent =>{ if (null! = Reader) reader. Dispose (); string text = antecedent. Result; Console. WriteLine (FormatBytes (text. Length) ;}); return task ;}

 

Before C #5.0, asynchronous request resources were completed. At first glance, it was very complicated, but compared with the above method, it seems that the idea is clear.

1. request. GetResponseAsync: create a task and wait for the response from the msdn server.

2. After obtaining the response, get the response stream and convert it to a string.

3. The next step is Unwrap. This should be the most difficult to understand. In fact, we only need to add this sentence to the idea of ContinueWith. The next step is to take the string directly.

4. The stream has been converted into a string. Just make a simple calculation.

Aoyi of Unwrap
public static Task<TResult> Unwrap<TResult>(this Task<Task<TResult>> task);

From the signature point of view, it is an extension method of the <Task <TResult> type, Task, Task with return value... dizzy, don't worry, wait for a while

Go back to the code and see what's going on

1. GetResponseAsync () creates a Task (meaning the same as the returned value, in order to differentiate the returned value of the Task). For a specific type of Task <WebResponse>, A WebResponse is returned after the Task ends.

 

2. the first ContinueWith caller is a Task, and the form parameter is a delegate that accepts a Task <WebReponse> and returns a Task <string> (via reader. readToEndAsync can be understood). The returned value is a Task. The problem is what its generic parameters are. First, the code in ContinueWith runs in a new working thread, we think of it as a main thread (just a relative environment). What task should the 'main thread' accomplish ?, He wants to take the execution result of the Task <WebResponse> WebResponse (although it is certain that this Task has been completed, but Microsoft has not done so ), then, create a Task <string> Based on the WebResponse as the return value of the current Working thread.

3. now the problem arises. We get a Task <string>. We can obtain this string by calling the Result twice, but in this ContinueWith block, it can only ensure that the outer Task is completed, so the second Result or the context thread is blocked.

Task task = request.GetResponseAsync()    .ContinueWith(antecedent =>    {        WebResponse response = antecedent.Result;        reader = new StreamReader(response.GetResponseStream());        return reader.ReadToEndAsync();    })    .ContinueWith(antecedent =>    {        var resTask = antecedent.Result;        var resString = resTask.Result;        if (null != reader)        {            string text = resString;            Console.WriteLine(FormatBytes(text.Length));        }    });

 

4. At this time, return to Unwarp (), which is to take off the outer Task, get the inner context thread of the Task, and use it as the main thread that continues the Task.

5. The Result retrieved here is a string, which is calculated and output.

 

ILSpy

After ILSpy decompilation, we can check that Unwarp () ensures that the tasks in the inner layer start to run and return the execution environment (context thread) of an inner layer task)

 

Related Article

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.