C#多线程并发编程深度探索:解锁async、await、Task与lock等关键字的奥秘

devtools/2024/11/14 11:52:04/

一、多线程介绍

1.什么是多线程

多线程是指在一个应用程序中同时执行多个线程的能力。每个线程都是独立运行的,拥有自己的执行路径和资源。多线程编程能够充分利用多核处理器的计算能力,提高应用程序的性能和响应性,特别是在处理耗时任务和并行计算时效果显著。

在C#中,线程是程序执行流的最小单元,每个线程都拥有独立的执行栈、程序计数器和本地变量。多线程编程允许程序同时执行多个线程,从而实现并发执行,提高程序的执行效率。

2.C#实现多线程的原理

C#实现多线程的原理主要依赖于操作系统对线程的支持和.NET Framework(或.NET Core/.NET 5+)提供的多线程编程模型。以下是一些关键点:

  1. 操作系统支持
    • 现代操作系统(如Windows、Linux等)都提供了对线程的支持,包括线程的创建、调度、同步等机制。
    • 操作系统负责管理线程的生命周期,包括分配CPU时间片给线程执行,以及在线程之间切换执行等。
  2. .NET Framework多线程编程模型
    • Thread类:C#中的System.Threading.Thread类是用于创建和管理线程的主要类。通过实例化Thread类并传递一个委托(如ThreadStartParameterizedThreadStart)给其构造函数,可以指定线程应执行的方法。
    • 线程池(ThreadPool):为了减少线程创建和销毁的开销,.NET Framework提供了线程池。线程池维护了一组工作线程,当需要执行新任务时,线程池会从池中取出一个空闲线程来执行任务,如果池中没有空闲线程,则可能会创建新线程(但受到一定限制)。
    • Task Parallel Library (TPL):TPL是.NET Framework中更高级别的多线程编程模型,它提供了TaskTask<TResult>类来简化异步编程。TPL能够自动管理线程,使得开发者可以更加专注于任务的逻辑,而不是线程的管理。
  3. 线程同步与通信
    • 多线程编程中,线程之间可能需要访问共享资源,这时就需要进行线程同步,以避免数据竞争和死锁等问题。C#中提供了多种同步机制,如锁(lock)、信号量(Semaphore)、互斥锁(Mutex)等。
    • 线程间通信可以通过共享内存、消息队列、事件等方式实现。在C#中,还可以使用Control.InvokeControl.BeginInvoke等方法在WinForms应用程序中从非UI线程更新UI元素。
  4. 异步编程
    • 异步编程是一种特殊的多线程编程方式,它允许在操作进行时释放主线程并继续执行其他任务,待操作完成后再回到主线程继续处理结果。C#中的asyncawait关键字为异步编程提供了强大的支持。

二、多线程实现方法

 

1. 使用Thread

这是最直接的方式,通过实例化System.Threading.Thread类来创建线程。你可以将ThreadStartParameterizedThreadStart委托传递给线程的构造函数,并在该委托中指定线程应执行的方法。

using System;  
using System.Threading;  class Program  
{  static void Main(string[] args)  {  Thread thread = new Thread(new ThreadStart(ThreadMethod));  thread.Start();  // 或者使用带参数的线程  Thread threadWithParam = new Thread(new ParameterizedThreadStart(ThreadMethodWithParam));  threadWithParam.Start("Hello, Thread!");  }  static void ThreadMethod()  {  Console.WriteLine("ThreadMethod is running.");  }  static void ThreadMethodWithParam(object param)  {  Console.WriteLine($"ThreadMethodWithParam is running with parameter: {param}");  }  
}

2. 使用Task

从.NET Framework 4.0开始,System.Threading.Tasks命名空间下的Task类提供了更高级别的并行和异步编程模型。TaskThread更易于使用,也更强大,因为它支持取消、等待和继续任务等操作。

using System;  
using System.Threading.Tasks;  class Program  
{  static void Main(string[] args)  {  Task task = Task.Run(() => {  Console.WriteLine("Task is running.");  });  task.Wait(); // 等待任务完成  // 或者使用异步等待  // Task.Run(async () => {  //     await Task.Delay(1000); // 模拟异步操作  //     Console.WriteLine("Task with async operation is running.");  // }).Wait();  }  
}

3. 使用ThreadPool

线程池(ThreadPool)是一种基于池的线程管理机制,它维护一个线程的集合,这些线程可以被重用,以减少线程创建和销毁的开销。当需要执行一个短时间操作时,使用线程池是一个好选择。

using System;  
using System.Threading;  class Program  
{  static void Main(string[] args)  {  ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod));  // 等待足够的时间以确保线程池中的线程完成  Thread.Sleep(1000);  }  static void ThreadMethod(object state)  {  Console.WriteLine("Thread from ThreadPool is running.");  }  
}

4. 使用asyncawait

asyncawait关键字用于简化异步编程模型。它们允许你以同步的方式编写异步代码,而不需要处理复杂的回调和状态管理。这通常与Task类一起使用。

using System;  
using System.Threading.Tasks;  class Program  
{  static async Task Main(string[] args)  {  await Task.Run(() => {  Console.WriteLine("Async operation is running.");  });  Console.WriteLine("Async operation completed.");  }  
}

三、不同方式之间的优缺点

在C#中实现多线程的几种方式(Thread类、Task类、ThreadPool以及async/await)之间存在几个关键的区别,这些区别主要体现在创建方式、使用场景、性能表现、功能丰富度以及易用性等方面。

1. Thread类

创建方式

  • 通过实例化System.Threading.Thread类并传递一个ThreadStartParameterizedThreadStart委托来创建线程。

使用场景

  • 适合需要直接控制线程生命周期、优先级等详细行为的场景。
  • 快速启动执行简单任务。

性能表现

  • 每次创建新线程都会有一定的开销,包括分配系统资源。
  • 频繁地创建和销毁线程可能会影响性能。

功能丰富度

  • 提供了对线程进行细致控制的能力,如设置优先级、名称等。

易用性

  • 需要手动管理线程的生命周期和同步问题,代码复杂度较高。

2. Task类

创建方式

  • 使用Task.Run方法或实例化Task类并调用其Start方法(虽然直接实例化并调用Start不是主要用法)。

使用场景

  • 现代.NET应用中推荐的异步编程方式。
  • 需要更好地管理异步操作、任务取消、异常处理等场景。

性能表现

  • 使用线程池来管理线程,减少了线程创建和销毁的开销。
  • 在多核处理器上能够更好地利用并行处理能力。

功能丰富度

  • 提供了丰富的API来管理任务,如等待任务完成、获取任务结果、任务取消等。

易用性

  • 通过async/await关键字可以方便地编写异步代码,降低了异步编程的复杂度。

3. ThreadPool

创建方式

  • 通过ThreadPool.QueueUserWorkItem方法将工作项(通常是一个委托)排入队列,由线程池自动调度执行。

使用场景

  • 需要高效利用线程池资源,执行大量短时间操作的场景。

性能表现

  • 减少了线程创建和销毁的开销,提高了性能。
  • 但由于全局队列的资源竞争,在高负载下可能会受到限制。

功能丰富度

  • 提供了基本的线程管理功能,但相比Thread和Task,控制度较低。

易用性

  • 使用相对简单,但对于复杂的异步操作和任务管理来说,功能可能不够丰富。

4. async/await

创建方式

  • 不是直接创建线程的方式,而是与Task类结合使用,以异步方式执行代码。

使用场景

  • 需要编写清晰、易于维护的异步代码的场景。
  • 适用于I/O密集型操作或需要提高程序响应性的场景。

性能表现

  • 通过异步方式提高了程序的响应性和吞吐量。
  • 在执行异步操作时不会阻塞调用线程。

功能丰富度

  • 提供了强大的异步编程模型,简化了异步代码的编写和维护。

易用性

  • 通过async/await关键字,可以以几乎同步的方式编写异步代码,提高了代码的可读性和可维护性。

综上所述,Thread类、Task类、ThreadPool以及async/await在C#中实现多线程的方式各有其特点和适用场景。在选择使用哪种方式时,应根据具体需求和场景来做出决策。


http://www.ppmy.cn/devtools/92269.html

相关文章

Ubuntu 22.04 Docker Network笔记

1、Docker容器的网络模式 Docker 容器的网络模式决定了容器如何与外部网络和其他容器通信。以下是 Docker 支持的主要网络模式及其特点&#xff1a; 桥接&#xff08;Bridge&#xff09;&#xff1a; 默认网络模式。每个容器都会连接到一个虚拟网桥&#xff08;bridge)上&…

SSH服务配置详细教程

一、对于CentOS系统 SSH(Secure Shell)服务配置是一个涉及多个步骤的过程,旨在确保远程登录和数据传输的安全性。以下是一个详细的SSH服务配置教程,以CentOS 7系统为例,但请注意,不同版本的Linux系统或Windows子系统中的步骤可能略有不同。 一、检查并安装SSH服务 检查…

[数据集][目标检测]轴承缺陷划痕检测数据集VOC+YOLO格式1166张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1166 标注数量(xml文件个数)&#xff1a;1166 标注数量(txt文件个数)&#xff1a;1166 标注…

【学习笔记】Day 9

一、进度概述 1、inversionnet_train 试运行——成功 二、详情 1、inversionnet_train 试运行 在经历了昨天的事故后&#xff0c;今天最终成功运行了 inversionnet_train&#xff0c;运行结果如下&#xff1a; 经观察&#xff0c;最开始 loss 值大概为 0.5 左右 随着训练量的增…

【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇 本篇为大家分享下在C学习中较为具有挑战与难度&#xff0c;同时也是很重要知识。掌握C类的六个默认成员函数&#xff0c;使得在模拟实现STL中容器过程得心应…

Spring Boot配置类的注解

Spring Boot 中&#xff0c;若某类只用 ConfigurationProperties 注解&#xff0c;然后该类&#xff1a; 没有在扫描路径下或没用 Component 等注解 就会导致无法被扫描为 bean&#xff0c;须在配置类用 EnableConfigurationProperties 注解去指定这个类&#xff0c;才能使 C…

使用tailwindcss轻松实现移动端rem适配

本示例节选自小卷全栈开发实战系列的《Vue3实战》。演示如何用tailwindcss所支持的rem体系轻松实现一个仿b站移动端头部导航栏rem适配。 友情声明 学习分享不易&#xff0c;如果小伙伴觉得有帮助&#xff0c;点赞支持下。满30赞&#xff0c;将随文附赠录屏讲解&#xff0c;感谢…

Gradio 快速开发网页应用

Gradio 是一个开源的 Python 框架&#xff0c;可以快速开发页面&#xff0c;Gradio 主要用于 AI 模型 Demo 的开发&#xff0c;通过几行代码可以快速生成一个 Web Demo&#xff0c;由于 AI 算法工程师使用的都是 Python 语言&#xff0c;使用 Python 开发 Demo 会相对简单&…