C# 实现多线程的几种方式
在C#中,实现多线程编程有多种方式,每种方式适用于不同的场景
使用 Thread 类
命名空间: System.Threading
特点: 最基础的多线程方式,直接控制线程的创建和管理
示例:
public class Program
{
public static void Main(string[] args)
{
// 不带参数的线程
Thread threada = new Thread(new ThreadStart(PalnA));
threada.Start();
// 带参数的线程
Thread threadb = new Thread(new ParameterizedThreadStart(PalnB));
threadb.Start("ParameterizedThreadStart");
Console.ReadKey();
}
public static void PalnA()
{
Console.WriteLine("ThreadStart");
}
public static void PalnB(object? param)
{
var message = param as string;
Console.WriteLine(message);
}
}适用场景:
需要精细控制线程生命周期(如优先级、前台/后台线程)。
简单、少量的线程任务。
缺点:
频繁创建/销毁线程开销大,不适合高并发。
使用 ThredPool 类
命名空间: System.Threading
特点: 重用线程,减少创建/销毁开销,适合短任务。
public class Program
{
public static void Main(string[] args)
{
// 使用ThredPool类
ThreadPool.QueueUserWorkItem(PalnB);
ThreadPool.QueueUserWorkItem(PalnB, "ThreadPool");
Console.ReadKey();
}
public static void PalnB(object? param)
{
var message = param as string;
Console.WriteLine(message);
}
}适用场景:
短时间完成的小任务(如文件I/O、网络请求)。
避免手动管理线程。
缺点:
无法控制线程优先级或直接获取返回值。
使用 Task.Run
命名空间: System.Threading.Tasks
特点: 基于线程池的高级抽象,支持异步操作、返回值和异常处理。
示例:
public class Program
{
public static async Task Main(string[] args)
{
// 使用异步方法
// 异步不等待
Task.Run(PlanA);
// 异步等待,不带返回值
await Task.Run(PlanA);
// 异步等待,带返回值
bool result = await Task.Run<bool>(PlanB);
// 阻塞直到结果返回
var task = Task.Run(PlanB);
// TO DO 其他事情
// ....
result = task.Result;
Console.ReadKey();
}
public static async Task PlanA()
{
Console.WriteLine("Task不带返回值");
}
public static bool PlanB()
{
Console.WriteLine("Task带返回值");
return true;
}
}适用场景:
异步编程(配合 async/await)。
需要任务链、延续或结果聚合(如 Task.ContinueWith)。
优点:
代码简洁,天然支持异步编程模型(APM)。
使用 Parallel 类 (数据并行)
命名空间: System.Threading.Tasks
特点: 自动并行化循环或任务,简化数据并行操作。
示例:
public class Program
{
public static async Task Main(string[] args)
{
// 使用Parallel 类(数据并行)
Parallel.For(0, 10, i => {
Console.WriteLine($"Parallel.For iteration {i}");
});
Parallel.ForEach(new[] { "A", "B", "C" }, item => {
Console.WriteLine($"Processing {item}");
});
Console.ReadKey();
}
}适用场景:
数据密集型并行计算(如矩阵运算、批量处理)。
替代传统 for/foreach 循环以提升性能。
注意:
需要避免共享资源的竞争条件。
适用场景:
I/O密集型操作(如文件读写、网络请求)。
需要保持UI线程响应的桌面/移动应用。
注意:async/await 本身不创建新线程,而是利用任务调度。
使用定时器
使用 System.Timers.Timer 或 System.Threading.Timer
特点: 定时触发任务,适合周期性操作。
示例:
System.Threading.Timer timer = new System.Threading.Timer(_ => {
Console.WriteLine("Timer tick!");
}, null, 0, 1000); // 立即启动,每隔1秒触发注意事项
线程安全:使用 lock、Monitor、Mutex 或并发集合(如 ConcurrentQueue)避免竞态条件。
资源释放:确保及时释放线程或任务占用的资源。