Asynchronous programming, c # asynchronous programming
Some time ago, I got a framework and didn't think much about it before. I just remember that there were a lot of Asynchronization.
public async Task<ActionResult> Login(LoginModel model, string returnUrl)
In the previous project, I have never used Asynchronization. Some people may confuse multithreading with Asynchronization. In fact, it is still different.
Now, let's take a look at Asynchronization for use. Here we will only introduce new methods. As for the old method, it is somewhat complicated and there is no new way to be intuitive and concise.
I. knowledge points
Asynchronous Method: Provides a simple way to complete the work that may take a long time to run without stopping the caller's thread. The caller of the asynchronous method can continue to work without waiting for the completion of the Asynchronous Method.
Await: The operator is applied to the task suspension method of An Asynchronous Method until the task is completed. Task indicates a job in progress.The await expression does not block the thread on which it executes.
Async: The async modifier indicates the method. It modifies the lambda expression or the anonymous method asynchronously.
Task class: It indicates a Task, which is supported in. net4.5 and belongs to the namespace System. Threading. Tasks. You can use the Task class to conveniently start a new thread.
Ii. Demo
1. mvc File Download
I have not mentioned the mvc source code parsing. In the default mode, mvc uses an Asynchronous Method to complete the work. Let's take a look at an application in mvc.
public class HomeController : Controller{ public async Task<FileResult> DownLoad(string name) { var path = Server.MapPath("~/FileRes/") + name; using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, FileOptions.Asynchronous)) { byte[] data = new byte[fs.Length]; await fs.ReadAsync(data, 0, data.Length); return File(data, "application/octet-stream", name); } }}
The File is read asynchronously. After the File is read, the fs is closed. Therefore, when the File is returned, the return File (fs, "application/octet-stream", name) is returned.
2. synchronous method call Asynchronous Method and Asynchronous Method call Asynchronous Method
static void Main(string[] args){ Console.WriteLine("Main Start : " + Thread.CurrentThread.ManagedThreadId); Step1(); Step2(); Console.WriteLine("Main End : " + Thread.CurrentThread.ManagedThreadId); Console.ReadKey();}static async void Step1(){ Console.WriteLine("Step1 start : " + Thread.CurrentThread.ManagedThreadId); try { await Task.Run(() => { Console.WriteLine("Step1.1 Current sleeping ThreadID : " + Thread.CurrentThread.ManagedThreadId); Thread.Sleep(3000); }); await Task.Run(() => { Console.WriteLine("Step1.2 Current sleeping ThreadID : " + Thread.CurrentThread.ManagedThreadId); Thread.Sleep(3000); Console.WriteLine("ThreadTest.Test Runing : " + Thread.CurrentThread.ManagedThreadId); }); } catch (Exception ex) { Console.WriteLine("ThreadTest : " + ex.Message); } await Step3(); Console.WriteLine("Step1 end : " +Thread.CurrentThread.ManagedThreadId);}static void Step2(){ Console.WriteLine("Step2 start : " + Thread.CurrentThread.ManagedThreadId); Console.WriteLine("Step2 Current ThreadID : " + Thread.CurrentThread.ManagedThreadId); Console.WriteLine("Step2 end : " + Thread.CurrentThread.ManagedThreadId);}static async Task Step3(){ Console.WriteLine("Step3 start : " + Thread.CurrentThread.ManagedThreadId); await Task.Run(() => { Console.WriteLine("Step3 Current sleeping ThreadID : " + Thread.CurrentThread.ManagedThreadId); Thread.Sleep(5000); }); Console.WriteLine("Step3 end : " + Thread.CurrentThread.ManagedThreadId);}
Main method call method step 2 is the synchronous method call synchronous method, call Step 1 is the synchronous method call Asynchronous Method.
The Step1 method calls the Step3 method, which is an asynchronous method call.
Running result:
Here I have run it several times. From the above results, we can see the following points:
1. the whole process of the main thread is not blocked and the execution ends.
If I add Thread in step 2. sleep (10), the main thread will be blocked here, waiting for the time in 10 s. I don't need to do anything. It's really nice.
2. When the Main thread encounters await wait in the Step1 method, it ignores it and directly returns to the Main method to execute the Step2 method.
This is what you should pay attention to when calling an Asynchronous Method for Synchronous methods, because the synchronous method does not handle await, and will not wait for the method execution after await to end here. Another point is that, the method in await will not be managed by the main program.
3. Note that the execution threads of Step1.1 and Step1.2 are sometimes the same and sometimes different. Why?
These threads should all be retrieved from the thread pool. In asynchronous methods, if the currently used thread does not need to be used, it will be returned to the thread pool and distributed by the thread pool, used by other threads. when the rest time is reached, the thread will be requested from the thread pool to complete the following work. it's a little like taking a taxi. When I get off the bus, I release the taxi resource. After an hour, I will go back and call another taxi, it may be the one you used. Of course it may not be. one advantage of doing so is to increase throughput and improve concurrent processing capability. if you have been waiting for you here, you don't have to pay for it. You have to pay less for it, and you don't have to pay much for it. Haha.
4. When Step1 calls Step3, it is obvious that the asynchronous method calls the asynchronous method, will it be like the previous synchronous method calls the asynchronous method?
From the above figure, we can clearly see that it is not the same. The effect is like the synchronous method called by the synchronous method. Here, we will always wait for you to get to the ground.
Conjecture:
If we analyze the asynchronous pending switching thread from the computer principle, I guess the process should be like this:
When the program runs until sleep, it will store the data into the memory and registers. when it encounters sleep, it will release the thread, enable the timer, trigger the timer to the point, and notify the thread pool, I need a thread to continue processing. When the thread pool receives a message, it will go to the pool to check which threads are available. If none are available, it will wait for a while, which may be 0.5s, if no available threads are released, a thread is created to meet the requirements and complete the work.
Refer:
Detailed description of. NET Asynchronization