A. Synchronous vs asynchronous
1. Synchronous VS Asynchronous VS Multithreading
Synchronous method: When called, you need to wait for the return result before you can continue to execute the business
Asynchronous methods: You can continue to perform business without waiting for the return result when calling
Start a new thread: Open a new thread outside the main thread to execute the business
The essential difference between synchronous and asynchronous methods: whether you need to wait for the return result to continue the business when calling
2. Common asynchronous methods (both end in Async)
(1) HttpClient classes: PostAsync, PutAsync, GetAsync, DeleteAsync
(2) DbContext class in EF: SaveChangesAsync
(3) File related: WriteLineAsync

3. Background on the introduction of asynchronous methods
For example, I want to get information from 2 interfaces in another server in the background, and then stitch the information of the two interfaces together and output them together, interface 1 takes 3s, interface 2 takes 5s,
(1) Traditional synchronization method:
The time required is about: 3s + 5s = 8s, as shown below [Case 1]
First share a synchronous request interface encapsulation method, the same below.
Then time-consuming operations on the sharing service, the same below.
Below is the code for Case 1
(2) Open a new thread to perform two time-consuming operations
The time required is approximately: Max(3s,5s) = 5s, as shown in [Case 2] below
Since the (2) method can solve the problem of synchronous method serial time consumption, but this method has a drawback, there are multiple threads in a business, and the need to manage threads is relatively troublesome, which leads to asynchronous methods.
The asynchronous method here I specifically refer to: the async-terminated asynchronous method that comes with the system class library.
(3) Use the asynchronous methods that come with the system class library
The time required is approximately: Max(3s,5s) = 5s, as shown in [Case 3] below
PS: By . Result to get the result after the asynchronous method has finished executing.
Second, use async and await to encapsulate asynchronous methods
1. A few points to start by stating:
(1) The async and await keywords were introduced in the C# 5.0 era and are an asynchronous programming model
(2) They don't create new threads by themselves, but I can use Task.Run to open new threads in my self-encapsulated async
(3) If all the methods used for async keyword encapsulation are written as serial services and do not use the await keyword, then even if the async encapsulation is used, it is useless and does not play the role of asynchronous method.
The time required is about: 3s + 5s = 8s, as shown in [Case 4] below, and the encapsulated method compiler will prompt: "Missing keyword await, will be called synchronously, use the await operator to wait for the form of a non-blocking API or Task.Run" (PS: non-blocking API refers to the asynchronous method ended with Async that comes with the system class library)
Conclusion 1: It can be concluded from (3) above that the async operator must have an effect on async, and that the effect operator can only be added before the asynchronous method provided by default by the system class library or a new thread (such as Task.Run).
For example, the time required for [Case 5] and [Case 6] below is about: Max(3s,5s) = 5s
2. Several rules and conventions
(1) In the method encapsulated by async, there can be multiple awaits, and here the await represents waiting for the line of code to finish executing.
(2) The methods we usually encapsulate ourselves should also end in Async for easy identification
(3) There are three main types of asynchronous returns: Task<T>, Task, void
3. The test draws several other conclusions
(1) If the async encapsulated asynchronous method has both synchronous and asynchronous services (opening a new thread or the system class library provides asynchronous methods), then the time of the synchronous method will block the main thread when it is called, that is, the main thread must wait for this part of the synchronous business to be executed before it can be executed downwards.
For example, [Case 7] Time-consuming: the sum of synchronous operations is 2s+2s + Max(3s,5s)=9s;
Proof: The time of synchronous traffic in the async encapsulated asynchronous method blocks the main thread, again proving that await can only be added before the non-blocking APIs and opening new threads
(2) If there is a wait problem in the encapsulated asynchronous method and the main thread cannot be blocked (thread.Sleep cannot be used), you can use Task.Delay and add the await keyword in front of it
For example, [Case 8] Time consuming: Max(2+3, 5+2)=7s
Iii. Asynchronous method return type
1. Task<T>, processes asynchronous methods with return values, via . Result waits for the asynchronous method to finish executing and gets the return value.
2. Task: Calling a method does not require a return value from the async method, but if you want to check the state of the async method, you can choose an object that can return a Task type. However, even if the async method contains a return statement, nothing is returned.
Such as [Case 9]
PS: For an asynchronous method with a Task return value, you can call Wait(), and when the async method is finished executing, unlike awari, await must appear in the method encapsulated by the async keyword.
3. Void: Calls the asynchronous execution method without any interaction
Such as [Case 10]
Several conclusions
1. Can an asynchronous method open a new thread?
The asynchronous and wait keywords do not cause other threads to be created. Because asynchronous methods themselves do not run threads, asynchronous methods do not require multithreading. Only when the + method is active, the method runs in the current synchronization context and is used at the time of the thread. You can use Task.Run to move CPU work to a background thread, but the background thread is not conducive to waiting for results to become available for processing. (From MSDN)
2. Async and await are asynchronous programming models that do not open new threads by themselves, but are mostly used to encapsulate some operations that do not block APIs or open new threads, so that they can be used like synchronous methods when they are called.
The following supplementary blog garden dudu explanation, easy for everyone to understand.