


Detailed explanation of graphic code of Thread, Task, Async/Await, IAsyncResult in C#
This article mainly introduces the relevant knowledge of Thread, Task, Async/Await, IAsyncResult in C#. It has a certain reference value, let’s take a look with the editor below
Speaking of asynchronous, Thread, Task, async/await, IAsyncResult, these things are definitely unavoidable. Let’s talk about them in turn today.
1. Thread
The meaning of multi-threading is that in an application, multiple execution parts can be executed at the same time; for more time-consuming operations ( For example, io, Database operations), or waiting for a response (such as WCF communication) The operation can be performed by starting the background thread separately, so that the main thread will not be blocked and can continue to execute; wait until the background thread is completed, then notify the main thread, and then make the corresponding operation!
In C#! It is relatively simple to start a new thread in
static void Main(string[] args) { Console.WriteLine("主线程开始"); //IsBackground=true,将其设置为后台线程 Thread t = new Thread(Run) { IsBackground = true }; t.Start(); Console.WriteLine("主线程在做其他的事!"); //主线程结束,后台线程会自动结束,不管有没有执行完成 //Thread.Sleep(300); Thread.Sleep(1500); Console.WriteLine("主线程结束"); } static void Run() { Thread.Sleep(700); Console.WriteLine("这是后台线程调用"); }
The execution result is as shown below,
You can see that after starting the background thread, the main thread continues to execute. It does not wait until the background thread is executed.
##1.1 Thread Pool
Imagine if there are a large number of tasks that need to be processed, such as the website background. For HTTP request processing, is it necessary to create a background thread for each request? It is obviously inappropriate. This will occupy a lot of memory, and the frequent creation process will also seriously affect the speed. So what should I do with the thread pool? In order to solve this problem, the created threads are stored to form a thread pool (with multiple threads in it). When a task is to be processed, if there are idle threads in the thread pool (after the previous task is completed, the thread will not be recycling, will be set to the idle state), then directly call the thread execution in the thread pool (for example, the Applicationobject in the asp.net processing mechanism),
Usage example:for (int i = 0; i < 10; i++) { ThreadPool.QueueUserWorkItem(m => { Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); }); } Console.Read();Running results:
#.
## 1.2 Semaphore Semaphore is responsible for coordinating threads and can limit the number of threads accessing a certain resource
Here is SemaphoreSlim A simple example of class usage:
static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问 static void Main(string[] args) { for (int i = 0; i < 10; i++) { new Thread(SemaphoreTest).Start(); } Console.Read(); } static void SemaphoreTest() { semLim.Wait(); Console.WriteLine("线程" + Thread.CurrentThread.ManagedThreadId.ToString() + "开始执行"); Thread.Sleep(2000); Console.WriteLine("线程" + Thread.CurrentThread.ManagedThreadId.ToString() + "执行完毕"); semLim.Release(); }
The execution results are as follows:
It can be seen that only three threads are executing at the beginning , when a thread is executed and released, a new thread will execute the method!
In addition to the SemaphoreSlim class, you can also use the Semaphore class, which feels more flexible. If you are interested, you can search it. Demonstration is done!
2.TaskTask was added to .NET4.0. It has similar functions to the thread pool ThreadPool. When you use Task to start a new task, it will be drawn from the thread pool. Calling thread, and Thread will create a new thread every time it is instantiated.
Console.WriteLine("主线程启动"); //Task.Run启动一个线程 //Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法 //Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); }); Task task = Task.Run(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); }); Thread.Sleep(300); task.Wait(); Console.WriteLine("主线程结束");
The execution results are as follows:
Method to start a new task: Task.Run() or Task.Factory.StartNew(), which opens the background Thread
To wait in the main thread for the background thread to complete execution, you can use the Wait method (it will be executed in a synchronous manner). Without Wait, it will be executed asynchronously.
Compare Task and Thread:
static void Main(string[] args) { for (int i = 0; i < 5; i++) { new Thread(Run1).Start(); } for (int i = 0; i < 5; i++) { Task.Run(() => { Run2(); }); } } static void Run1() { Console.WriteLine("Thread Id =" + Thread.CurrentThread.ManagedThreadId); } static void Run2() { Console.WriteLine("Task调用的Thread Id =" + Thread.CurrentThread.ManagedThreadId); }
Execution result:
It can be seen that using Thread directly will open 5 threads. Use Task (using thread pool) to open 3!
2.1 TaskConsole.WriteLine("主线程开始");
//返回值类型为string
Task<string> task = Task<string>.Run(() => {
Thread.Sleep(2000);
return Thread.CurrentThread.ManagedThreadId.ToString();
});
//会等到task执行完毕才会输出;
Console.WriteLine(task.Result);
Console.WriteLine("主线程结束");
The return value can be obtained through task.Result. If the background thread has not finished executing when the value is obtained, it will Wait for it to complete!
3. async/await
async/await was introduced in C# 5.0, first usage:
static void Main(string[] args) { Console.WriteLine("-------主线程启动-------"); Task<int> task = GetStrLengthAsync(); Console.WriteLine("主线程继续执行"); Console.WriteLine("Task返回的值" + task.Result); Console.WriteLine("-------主线程结束-------"); } static async Task<int> GetStrLengthAsync() { Console.WriteLine("GetStrLengthAsync方法开始执行"); //此处返回的<string>中的字符串类型,而不是Task<string> string str = await GetString(); Console.WriteLine("GetStrLengthAsync方法执行结束"); return str.Length; } static Task<string> GetString() { //Console.WriteLine("GetString方法开始执行") return Task<string>.Run(() => { Thread.Sleep(2000); return "GetString的返回值"; }); }async is used to modify methods , indicating that this method is asynchronous, and the return type of the declared method must be: void, Task or Task
await必须用来修饰Task或Task
看看运行结果:
可以看出来,main函数调用GetStrLengthAsync方法后,在await之前,都是同步执行的,直到遇到await关键字,main函数才返回继续执行。
那么是否是在遇到await关键字的时候程序自动开启了一个后台线程去执行GetString方法呢?
现在把GetString方法中的那行注释加上,运行的结果是:
大家可以看到,在遇到await关键字后,没有继续执行GetStrLengthAsync方法后面的操作,也没有马上反回到main函数中,而是执行了GetString的第一行,以此可以判断await这里并没有开启新的线程去执行GetString方法,而是以同步的方式让GetString方法执行,等到执行到GetString方法中的Task
那么await的作用是什么呢?
可以从字面上理解,上面提到task.wait可以让主线程等待后台线程执行完毕,await和wait类似,同样是等待,等待Task
那么await是怎么做到的呢?有没有开启新线程去等待?
只有两个线程(主线程和Task开启的线程)!至于怎么做到的(我也不知道......>_
4.IAsyncResult
IAsyncResult自.NET1.1起就有了,包含可异步操作的方法的类需要实现它,Task类就实现了该接口
在不借助于Task的情况下怎么实现异步呢?
class Program { static void Main(string[] args) { Console.WriteLine("主程序开始--------------------"); int threadId; AsyncDemo ad = new AsyncDemo(); AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod); IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null); Thread.Sleep(0); Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId) //会阻塞线程,直到后台线程执行完毕之后,才会往下执行 result.AsyncWaitHandle.WaitOne(); Console.WriteLine("主程序在做一些事情!!!"); //获取异步执行的结果 string returnValue = caller.EndInvoke(out threadId, result); //释放资源 result.AsyncWaitHandle.Close(); Console.WriteLine("主程序结束--------------------"); Console.Read(); } } public class AsyncDemo { //供后台线程执行的方法 public string TestMethod(int callDuration, out int threadId) { Console.WriteLine("测试方法开始执行."); Thread.Sleep(callDuration); threadId = Thread.CurrentThread.ManagedThreadId; return String.Format("测试方法执行的时间 {0}.", callDuration.ToString()); } } public delegate string AsyncMethodCaller(int callDuration, out int threadId);
关键步骤就是红色字体的部分,运行结果:
和Task的用法差异不是很大!result.AsyncWaitHandle.WaitOne()就类似Task的Wait。
5.Parallel
最后说一下在循环中开启多线程的简单方法:
Stopwatch watch1 = new Stopwatch(); watch1.Start(); for (int i = 1; i <= 10; i++) { Console.Write(i + ","); Thread.Sleep(1000); } watch1.Stop(); Console.WriteLine(watch1.Elapsed); Stopwatch watch2 = new Stopwatch(); watch2.Start(); //会调用线程池中的线程 Parallel.For(1, 11, i => { Console.WriteLine(i + ",线程ID:" + Thread.CurrentThread.ManagedThreadId); Thread.Sleep(1000); }); watch2.Stop(); Console.WriteLine(watch2.Elapsed);
运行结果:
循环List
List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 }; Parallel.ForEach<int>(list, n => { Console.WriteLine(n); Thread.Sleep(1000); });
Action[] actions = new Action[] { new Action(()=>{ Console.WriteLine("方法1"); }), new Action(()=>{ Console.WriteLine("方法2"); }) }; Parallel.Invoke(actions);
The above is the detailed content of Detailed explanation of graphic code of Thread, Task, Async/Await, IAsyncResult in C#. For more information, please follow other related articles on the PHP Chinese website!

C# and .NET provide powerful features and an efficient development environment. 1) C# is a modern, object-oriented programming language that combines the power of C and the simplicity of Java. 2) The .NET framework is a platform for building and running applications, supporting multiple programming languages. 3) Classes and objects in C# are the core of object-oriented programming. Classes define data and behaviors, and objects are instances of classes. 4) The garbage collection mechanism of .NET automatically manages memory to simplify the work of developers. 5) C# and .NET provide powerful file operation functions, supporting synchronous and asynchronous programming. 6) Common errors can be solved through debugger, logging and exception handling. 7) Performance optimization and best practices include using StringBuild

.NETFramework is a cross-language, cross-platform development platform that provides a consistent programming model and a powerful runtime environment. 1) It consists of CLR and FCL, which manages memory and threads, and FCL provides pre-built functions. 2) Examples of usage include reading files and LINQ queries. 3) Common errors involve unhandled exceptions and memory leaks, and need to be resolved using debugging tools. 4) Performance optimization can be achieved through asynchronous programming and caching, and maintaining code readability and maintainability is the key.

Reasons for C#.NET to remain lasting attractive include its excellent performance, rich ecosystem, strong community support and cross-platform development capabilities. 1) Excellent performance and is suitable for enterprise-level application and game development; 2) The .NET framework provides a wide range of class libraries and tools to support a variety of development fields; 3) It has an active developer community and rich learning resources; 4) .NETCore realizes cross-platform development and expands application scenarios.

Design patterns in C#.NET include Singleton patterns and dependency injection. 1.Singleton mode ensures that there is only one instance of the class, which is suitable for scenarios where global access points are required, but attention should be paid to thread safety and abuse issues. 2. Dependency injection improves code flexibility and testability by injecting dependencies. It is often used for constructor injection, but it is necessary to avoid excessive use to increase complexity.

C#.NET is widely used in the modern world in the fields of game development, financial services, the Internet of Things and cloud computing. 1) In game development, use C# to program through the Unity engine. 2) In the field of financial services, C#.NET is used to develop high-performance trading systems and data analysis tools. 3) In terms of IoT and cloud computing, C#.NET provides support through Azure services to develop device control logic and data processing.

.NETFrameworkisWindows-centric,while.NETCore/5/6supportscross-platformdevelopment.1).NETFramework,since2002,isidealforWindowsapplicationsbutlimitedincross-platformcapabilities.2).NETCore,from2016,anditsevolutions(.NET5/6)offerbetterperformance,cross-

The C#.NET developer community provides rich resources and support, including: 1. Microsoft's official documents, 2. Community forums such as StackOverflow and Reddit, and 3. Open source projects on GitHub. These resources help developers improve their programming skills from basic learning to advanced applications.

The advantages of C#.NET include: 1) Language features, such as asynchronous programming simplifies development; 2) Performance and reliability, improving efficiency through JIT compilation and garbage collection mechanisms; 3) Cross-platform support, .NETCore expands application scenarios; 4) A wide range of practical applications, with outstanding performance from the Web to desktop and game development.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 English version
Recommended: Win version, supports code prompts!

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

Dreamweaver Mac version
Visual web development tools

Atom editor mac version download
The most popular open source editor
