C# 并发与多线程:从入门到精通——完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么 C# 需要并发?

现代应用程序越来越需要同时执行多个操作。用户期望界面在加载数据时不会“卡死”,而服务器能够并行处理数千个请求。在 C# (.NET) 中,解决这些问题需要使用并发——程序在重叠的时间段内执行多个任务的能力,以及多线程——通过多个执行线程实现并发的方式。

在本文中,我们将剖析关键概念:从基础的 Thread 到现代的 async/await 和 Parallel。您将学习如何为每个任务正确选择工具,并避免常见错误,例如死锁 (deadlocks) 和竞态条件 (race conditions)。



1. 基础:Thread 和 ThreadPool

通过 Thread 使用线程

System.Threading.Thread 类是最底层的线程创建方式。每个线程都有自己的堆栈并独立执行。创建和启动线程的示例:

using System;using System.Threading;

class Program{ static void Main() { Thread thread = new Thread(DoWork); thread.Start(); // 主线程继续工作 for (int i = 0; i < 5; i++) { Console.WriteLine($"主线程: {i}"); Thread.Sleep(100); } thread.Join(); // 等待子线程完成 }

static void DoWork() { for (int i = 0; i < 5; i++) { Console.WriteLine($"工作线程: {i}"); Thread.Sleep(150); } }}

重要提示: 创建新线程是一项昂贵的操作。对于频繁创建短生命周期线程的情况,最好使用 ThreadPool。



ThreadPool——线程池

ThreadPool 管理一组可重复使用的工作线程。这比手动创建 Thread 更高效。示例:

ThreadPool.QueueUserWorkItem(state =>{    Console.WriteLine("任务在线程池中执行");    Thread.Sleep(500);    Console.WriteLine("任务完成");});

Console.WriteLine("主线程继续工作");Console.ReadKey();

限制: 您无法直接管理线程池中线程的优先级或名称。如需更精细的控制,请使用 Task。



2. Task 和任务并行库 (TPL)

Task——现代方法

从 .NET 4.0 开始,Task 成为异步操作的主要工具。它抽象了线程,并允许处理执行结果。示例:

using System;using System.Threading.Tasks;

class Program{ static async Task Main() { Task<int> task = Task.Run(() => ComputeResult(10)); // 可以执行其他工作 Console.WriteLine("等待结果..."); int result = await task; Console.WriteLine($"结果: {result}"); }

static int ComputeResult(int value) { Task.Delay(1000).Wait(); // 模拟耗时操作 return value * 2; }}

主要优势:

  • 通过 Task<T> 返回结果
  • 支持通过 CancellationToken 取消
  • 允许组合任务 (ContinueWith, WhenAll, WhenAny)
  • 与 async/await 集成


Parallel——用于并行循环

Parallel 类简化了并行循环的执行。示例:

using System;using System.Threading.Tasks;

class Program{ static void Main()\

博客

书籍推荐