C# 多线程编程精通:提升性能与效率的核心技术
线程基础
线程是程序的执行路径。每个线程定义唯一的控制流。若应用涉及复杂耗时操作,设置不同执行路径或线程很有帮助,每个线程执行特定任务。
线程是轻量级进程。现代操作系统实现并发编程常用线程。使用线程可节省 CPU 周期,提高应用效率。
此前我们编写的程序中单线程作为单进程运行。但这方式应用一次只能执行一项任务。为使其同时执行多任务,可将其分解为更小的线程。
线程生命周期
线程生命周期始于创建 System.Threading.Thread 类对象,终于线程终止或执行完成。
线程生命周期的各种状态:
- 未启动状态:创建线程实例但未调用 Start 方法。
- 就绪状态:线程准备好运行,等待 CPU 周期。
- 不可运行状态:线程不可执行,当:
- 调用了 Sleep 方法
- 调用了 Wait 方法
- 被 I/O 操作阻塞
- 死亡状态:线程执行完成或被中止。
主线程
在 C# 中,System.Threading.Thread 类用于处理线程,允许在多线程应用中创建和访问单个线程。进程中第一个执行的线程称为主线程。
C# 程序开始执行时自动创建主线程。使用 Thread 类创建的线程称为主线程的子线程。可通过 Thread 类的 CurrentThread 属性访问线程。
以下程序演示主线程执行:
在线演示using System;
using System.Threading;
namespace MultithreadingApplication {
class MainThreadProgram {
static void Main(string[] args) {
Thread th = Thread.CurrentThread;
th.Name = "MainThread";
Console.WriteLine("This is {0}", th.Name);
Console.ReadKey();
}
}
}
编译执行上述代码,输出结果如下:
This is MainThread
Thread 类的常用属性与方法
常用属性
| 序号 | 属性与说明 |
|---|---|
| 1 | CurrentContext - 获取线程正在其中执行的当前上下文。 |
| 2 | CurrentCulture - 获取或设置当前线程的区域性。 |
| 3 | CurrentPrinciple - 获取或设置线程的当前主体(基于角色的安全性)。 |
| 4 | CurrentThread - 获取当前正在运行的线程。 |
| 5 | CurrentUICulture - 获取或设置资源管理器在运行时查找区域性特定资源所用的当前区域性。 |
| 6 | ExecutionContext - 获取包含当前线程各种上下文信息的 ExecutionContext 对象。 |
| 7 | IsAlive - 获取指示当前线程执行状态的值。 |
| 8 | IsBackground - 获取或设置指示线程是否为后台线程的值。 |
| 9 | IsThreadPoolThread - 获取指示线程是否属于托管线程池的值。 |
| 10 | ManagedThreadId - 获取当前托管线程的唯一标识符。 |
| 11 | Name - 获取或设置线程名称。 |
| 12 | Priority - 获取或设置线程的调度优先级。 |
| 13 | ThreadState - 获取包含当前线程状态的值。 |
常用方法
| 序号 | 方法与说明 |
|---|---|
| 1 | Abort() - 在调用线程上引发 ThreadAbortException 以开始终止线程过程。 |
| 2 | Start() - 启动线程。 |
| 3 | Sleep(int millisecondsTimeout) - 让线程暂停一段时间。 |
| 4 | Join() - 阻塞调用线程直到某线程终止。 |
| 5 | Interrupt() - 中断处于 WaitSleepJoin 状态的线程。 |
| 6 | ResetAbort() - 取消对当前线程的 Abort 请求。 |
| 7 | Yield() - 让调用线程让出执行权给准备好在当前处理器上运行的另一个线程。 |
| 8 | VolatileRead/VolatileWrite - 读写字段值,确保对所有处理器可见。 |
| 9 | MemoryBarrier() - 同步内存访问,防止指令重排序。 |
| 10 | SpinWait(int iterations) - 让线程等待迭代参数定义的次数。 |
创建线程
通过扩展 Thread 类创建线程。扩展的 Thread 类调用 Start() 方法开始子线程执行。
以下程序演示该概念:
在线演示using System;
using System.Threading;
namespace MultithreadingApplication {
class ThreadCreationProgram {
public static void CallToChildThread() {
Console.WriteLine("Child thread starts");
}
static void Main(string[] args) {
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
}
}
编译执行上述代码,输出结果如下:
In Main: Creating the Child thread Child thread starts
管理线程
Thread 类提供多种管理线程的方法。以下示例演示使用 Sleep() 方法让线程暂停特定时间:
在线演示using System;
using System.Threading;
namespace MultithreadingApplication {
class ThreadCreationProgram {
public static void CallToChildThread() {
Console.WriteLine("Child thread starts");
int sleepfor = 5000;
Console.WriteLine("Child Thread Paused for {0} seconds", sleepfor / 1000);
Thread.Sleep(sleepfor);
Console.WriteLine("Child thread resumes");
}
static void Main(string[] args) {
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
}
}
编译执行上述代码,输出结果如下:
In Main: Creating the Child thread Child thread starts Child Thread Paused for 5 seconds Child thread resumes
销毁线程
Abort() 方法用于销毁线程。运行时通过抛出 ThreadAbortException 中止线程。此异常无法捕获,控制权传递给 finally 块(如有)。
以下程序演示此过程:
在线演示using System;
using System.Threading;
namespace MultithreadingApplication {
class ThreadCreationProgram {
public static void CallToChildThread() {
try {
Console.WriteLine("Child thread starts");
for (int counter = 0; counter <= 10; counter++) {
Thread.Sleep(500);
Console.WriteLine(counter);
}
Console.WriteLine("Child Thread Completed");
} catch (ThreadAbortException e) {
Console.WriteLine("Thread Abort Exception");
} finally {
Console.WriteLine("Couldn't catch the Thread Exception");
}
}
static void Main(string[] args) {
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Thread.Sleep(2000);
Console.WriteLine("In Main: Aborting the Child thread");
childThread.Abort();
Console.ReadKey();
}
}
}
编译执行上述代码,输出结果如下:
In Main: Creating the Child thread Child thread starts 0 1 2 In Main: Aborting the Child thread Thread Abort Exception Couldn't catch the Thread Exception
C语言