search
HomeBackend DevelopmentC#.Net TutorialDetailed 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 Application

object 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:

It can be seen that although it was executed 10 times, 10 threads were not created

#.

## 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.Task

Task 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 Task##Task is a Task with a return value, and TResult is the return value type.

Console.WriteLine("主线程开始");
//返回值类型为string
Task<string> task = Task<string>.Run(() => {
 Thread.Sleep(2000); 
 return Thread.CurrentThread.ManagedThreadId.ToString(); 
});
//会等到task执行完毕才会输出;
Console.WriteLine(task.Result);
Console.WriteLine("主线程结束");

Running result:

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!

A brief mention:

Task tasks can be canceled through the CancellationTokenSource class. I feel that it is not used much and the usage is relatively simple. If you are interested, you can search it!

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,而且只能出现在已经用async关键字修饰的异步方法中。通常情况下,async/await成对出现才有意义,

看看运行结果:

可以看出来,main函数调用GetStrLengthAsync方法后,在await之前,都是同步执行的,直到遇到await关键字,main函数才返回继续执行。

那么是否是在遇到await关键字的时候程序自动开启了一个后台线程去执行GetString方法呢?

现在把GetString方法中的那行注释加上,运行的结果是:

大家可以看到,在遇到await关键字后,没有继续执行GetStrLengthAsync方法后面的操作,也没有马上反回到main函数中,而是执行了GetString的第一行,以此可以判断await这里并没有开启新的线程去执行GetString方法,而是以同步的方式让GetString方法执行,等到执行到GetString方法中的Task.Run()的时候才由Task开启了后台线程!

那么await的作用是什么呢?

可以从字面上理解,上面提到task.wait可以让主线程等待后台线程执行完毕,await和wait类似,同样是等待,等待Task.Run()开始的后台线程执行完毕,不同的是await不会阻塞主线程,只会让GetStrLengthAsync方法暂停执行。

那么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[]数组里面的方法:

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!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
C# and .NET: Understanding the Relationship Between the TwoC# and .NET: Understanding the Relationship Between the TwoApr 17, 2025 am 12:07 AM

The relationship between C# and .NET is inseparable, but they are not the same thing. C# is a programming language, while .NET is a development platform. C# is used to write code, compile into .NET's intermediate language (IL), and executed by the .NET runtime (CLR).

The Continued Relevance of C# .NET: A Look at Current UsageThe Continued Relevance of C# .NET: A Look at Current UsageApr 16, 2025 am 12:07 AM

C#.NET is still important because it provides powerful tools and libraries that support multiple application development. 1) C# combines .NET framework to make development efficient and convenient. 2) C#'s type safety and garbage collection mechanism enhance its advantages. 3) .NET provides a cross-platform running environment and rich APIs, improving development flexibility.

From Web to Desktop: The Versatility of C# .NETFrom Web to Desktop: The Versatility of C# .NETApr 15, 2025 am 12:07 AM

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C# .NET and the Future: Adapting to New TechnologiesC# .NET and the Future: Adapting to New TechnologiesApr 14, 2025 am 12:06 AM

C# and .NET adapt to the needs of emerging technologies through continuous updates and optimizations. 1) C# 9.0 and .NET5 introduce record type and performance optimization. 2) .NETCore enhances cloud native and containerized support. 3) ASP.NETCore integrates with modern web technologies. 4) ML.NET supports machine learning and artificial intelligence. 5) Asynchronous programming and best practices improve performance.

Is C# .NET Right for You? Evaluating its ApplicabilityIs C# .NET Right for You? Evaluating its ApplicabilityApr 13, 2025 am 12:03 AM

C#.NETissuitableforenterprise-levelapplicationswithintheMicrosoftecosystemduetoitsstrongtyping,richlibraries,androbustperformance.However,itmaynotbeidealforcross-platformdevelopmentorwhenrawspeediscritical,wherelanguageslikeRustorGomightbepreferable.

C# Code within .NET: Exploring the Programming ProcessC# Code within .NET: Exploring the Programming ProcessApr 12, 2025 am 12:02 AM

The programming process of C# in .NET includes the following steps: 1) writing C# code, 2) compiling into an intermediate language (IL), and 3) executing by the .NET runtime (CLR). The advantages of C# in .NET are its modern syntax, powerful type system and tight integration with the .NET framework, suitable for various development scenarios from desktop applications to web services.

C# .NET: Exploring Core Concepts and Programming FundamentalsC# .NET: Exploring Core Concepts and Programming FundamentalsApr 10, 2025 am 09:32 AM

C# is a modern, object-oriented programming language developed by Microsoft and as part of the .NET framework. 1.C# supports object-oriented programming (OOP), including encapsulation, inheritance and polymorphism. 2. Asynchronous programming in C# is implemented through async and await keywords to improve application responsiveness. 3. Use LINQ to process data collections concisely. 4. Common errors include null reference exceptions and index out-of-range exceptions. Debugging skills include using a debugger and exception handling. 5. Performance optimization includes using StringBuilder and avoiding unnecessary packing and unboxing.

Testing C# .NET Applications: Unit, Integration, and End-to-End TestingTesting C# .NET Applications: Unit, Integration, and End-to-End TestingApr 09, 2025 am 12:04 AM

Testing strategies for C#.NET applications include unit testing, integration testing, and end-to-end testing. 1. Unit testing ensures that the minimum unit of the code works independently, using the MSTest, NUnit or xUnit framework. 2. Integrated tests verify the functions of multiple units combined, commonly used simulated data and external services. 3. End-to-end testing simulates the user's complete operation process, and Selenium is usually used for automated testing.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools