C#Thread Learning Note 8: Getting Started with async & await

1. Contents involved

Async & await was introduced in C# 5.0, and the $symbol (stitched string) used for console output was introduced in C# 6.0, which functions like the string.Format() method.

2. Relations and differences among multi-threading, asynchronous and synchronous

Kitchen case:

For example, if you want to fry 5 dishes ABCDE, only two stoves can be used, that is, only two dishes can be fried at the same time.Here, the stove is the thread.

If two ovens fry A and B at the same time, the remaining CDE can only start when A or B has finished frying.The waiting process is synchronization, which we call blocking, where you can only fry two dishes, A and B.

If you still have a coffee machine, put the coffee beans and water in the coffee machine to switch on while you fry A and B, and then you don't care about it.At this point, a new thread is opened to brew coffee and coffee

It is automatically done by the coffee machine and does not affect the continued cooking, so the thread of brewing coffee is asynchronous, which we call non-blocking.

When the coffeemaker rings to inform you that the coffee is ready and you want to take it out with some sugar or milk or something, this coffee-taking action we call callback, which is to notify you when the coffeemaker thread is finished

Actions done.

In short:

Tasks that take up your time so you can't do anything else are called synchronous tasks (focus on cooking or you'll get burnt).

Those tasks that don't take up your time are called asynchronous tasks (coffee machines cook the coffee themselves without you having to look at it all the time).

The following code demonstrates the case where asynchronous is not used:

    class Program
    {
        //Create a timer
        private static readonly Stopwatch stopwatch = new Stopwatch();

        static void Main(string[] args)
        {
            #region async & await Getting Started Without Asynchronization
            //Start timer
            stopwatch.Start();
            //URL address
            const string url1 = "http://www.cnblogs.com/";
            const string url2 = "http://www.cnblogs.com/atomy/";
            //Download content from a website asynchronously and count the number of characters.
            var result1 = CountCharacters("url1", url1);
            var result2 = CountCharacters("url2", url2);
            //Time-consuming operations mainly through stitching strings
            for (var i = 0; i < 3; i++)
            {
                ExtraOperation(i + 1);
            }
            //console output
            Console.WriteLine($"{url1} Number of characters for:{result1}");
            Console.WriteLine($"{url2} Number of characters for:{result2}");
            Console.WriteLine($"Time taken for tests{stopwatch.ElapsedMilliseconds}ms. ");
            Console.Read();
            #endregion
        }

        /// <summary>
        /// Count number of characters
        /// </summary>
        /// <param name="id"></param>
        /// <param name="address"></param>
        /// <returns></returns>
        private static int CountCharacters(string name, string address)
        {
            var wc = new WebClient();
            Console.WriteLine($"{name}Start call, duration{stopwatch.ElapsedMilliseconds}ms,thread id={Thread.CurrentThread.ManagedThreadId}. ");

            var result = wc.DownloadString(address);
            Console.WriteLine($"{name}Call completed, elapsed{stopwatch.ElapsedMilliseconds}ms,thread id={Thread.CurrentThread.ManagedThreadId}. ");

            return result.Length;
        }

        /// <summary>
        /// Additional operations
        /// </summary>
        /// <param name="id"></param>
        private static void ExtraOperation(int id)
        {
            //Here are some relatively time-consuming operations by stitching strings
            var s = "";
            for (var i = 0; i < 6000; i++)
            {
                s += i;
            }
            Console.WriteLine($"No.{id}second ExtraOperation Execution is complete and takes:{stopwatch.ElapsedMilliseconds}ms. ");
        }
    }

The results are as follows:

The following code demonstrates the use of asynchronous:

    class Program
    {
        //Create a timer
        private static readonly Stopwatch stopwatch = new Stopwatch();

        static void Main(string[] args)
        {
            #region async & await Getting Started Using Asynchronous
            //Start timer
            stopwatch.Start();
            //URL address
            const string url1 = "http://www.cnblogs.com/";
            const string url2 = "http://www.cnblogs.com/atomy/";
            //Download content from a website asynchronously and count the number of characters.
            Task<int> t1 = CountCharactersAsync("url1", url1);
            Task<int> t2 = CountCharactersAsync("url2", url2);
            //Time-consuming operations mainly through stitching strings
            for (var i = 0; i < 3; i++)
            {
                ExtraOperation(i + 1);
            }
            //console output
            Console.WriteLine($"{url1} Number of characters for:{t1.Result}");
            Console.WriteLine($"{url2} Number of characters for:{t2.Result}");
            Console.WriteLine($"Time taken for tests{stopwatch.ElapsedMilliseconds}ms. ");
            Console.Read();
            #endregion
        }

        /// <summary>
        /// Count number of characters
        /// </summary>
        /// <param name="id"></param>
        /// <param name="address"></param>
        /// <returns></returns>
        private static async Task<int> CountCharactersAsync(string name, string address)
        {
            var wc = new WebClient();
            Console.WriteLine($"{name}Start call, duration{stopwatch.ElapsedMilliseconds}ms,thread id={Thread.CurrentThread.ManagedThreadId}. ");

            var result =await wc.DownloadStringTaskAsync(address);
            Console.WriteLine($"{name}Call completed, elapsed{stopwatch.ElapsedMilliseconds}ms,thread id={Thread.CurrentThread.ManagedThreadId}. ");

            return result.Length;
        }

        /// <summary>
        /// Additional operations
        /// </summary>
        /// <param name="id"></param>
        private static void ExtraOperation(int id)
        {
            //Here are some relatively time-consuming operations by stitching strings
            var s = "";
            for (var i = 0; i < 6000; i++)
            {
                s += i;
            }
            Console.WriteLine($"No.{id}second ExtraOperation Execution is complete and takes:{stopwatch.ElapsedMilliseconds}ms. ");
        }
    }

The results are as follows:

3. async & await structure

The async & await structure can be divided into three parts:

1) Call method: This method calls an asynchronous method and then proceeds while the asynchronous method performs its tasks;

2) Asynchronous method: the method performs its work asynchronously and immediately returns to the calling method;

3) await expression: used inside asynchronous methods to indicate tasks that need to be executed asynchronously.An asynchronous method can contain more than one await expression (the IDE warns if no await expression exists).

IV. Asynchronous methods

Asynchronous method: Return the calling method immediately before execution is complete, and complete the task while the calling method continues execution.

Grammatical Analysis:

1) Keyword: Method header uses async modifier.
2) Requirement: await expression (may be multiple) is required for asynchronous operation, otherwise it is considered a common method for synchronous operation.
3) Return type: Only three types can be returned (void, Task, and Task<T>).Task and Task<T>Identify that the returned object will complete its work in the future, indicating that the calling method and the asynchronous method can continue to execute.
4) Parameters: unlimited number, but out and ref keywords cannot be used.
5) Naming convention: method suffix name should end with Async.

Reference from:

    https://www.cnblogs.com/woxihuadabai/p/8042652.html

    https://www.cnblogs.com/liqingwen/p/5831951.html

Keywords: C# brew

Added by blueman378 on Sat, 14 Dec 2019 10:41:47 +0200