编辑
2025-09-24
C#
00

目录

摘要
正文
1. 创建线程
2. 启动线程
3. 挂起线程
4. 线程等待
5. 恢复线程
6. 终止线程
示例
创建线程
线程等待
终止线程
注意

摘要

在C#中,线程的生命周期是由多个状态组成的,这些状态包括线程的创建、启动、挂起、等待、恢复和终止。

正文

1. 创建线程

线程的生命周期从创建开始。在C#中,可以通过System.Threading.Thread类的实例化来创建一个线程。创建线程时,需要指定一个将在该线程上执行的方法。

C#
Thread myThread = new Thread(new ThreadStart(MyMethod));

这里,MyMethod是一个无参方法,它定义了线程的执行内容。

2. 启动线程

创建线程后,它处于就绪状态,等待CPU的调度。通过调用Thread对象的Start方法来启动线程,使其进入可运行状态。

C#
myThread.Start();

一旦线程开始执行,它会自动地调用其对应的方法。

3. 挂起线程

线程可以被显式地挂起,即暂时停止执行,这通常是通过调用Suspend方法实现的。不过,需要注意的是,Suspend方法在.NET Framework 2.0之后已被弃用,因为它可能导致死锁。现在建议使用其他同步技术,如ManualResetEventMonitor等。

4. 线程等待

线程在执行过程中,可能会因为某些条件未满足而进入等待状态。例如,当线程调用Join方法等待另一个线程完成时,或者使用Thread.Sleep暂停当前线程的执行。

C#
myThread.Join(); // 等待myThread线程完成 Thread.Sleep(1000); // 当前线程暂停1秒

5. 恢复线程

对于被挂起的线程,可以通过调用Resume方法来恢复其执行。同样地,Resume方法也已被弃用,建议使用其他同步机制来控制线程的执行。

6. 终止线程

线程的执行可以通过多种方式结束:

  • 线程的执行方法完成执行。
  • 调用线程的Abort方法来请求终止线程。不过,Abort方法在.NET Core中已经不再支持,因为它可能导致应用程序状态不一致。
  • 抛出未被捕获的异常也会导致线程终止。

线程一旦终止,它的状态变为Stopped,此时它的生命周期结束。

因为我们是用Winform做线程实例,所以需要跨线程UI操作的一些技术。

示例

一个例子,点击开始,会在文本框中每10毫秒输出一个点。

image.png

创建线程

通过new 一个Thread对象并指定线程执行函数创建线程。调用Start方法开启线程

C#
private void btnStart_Click(object sender, EventArgs e) { Thread thread = new Thread(ShowDot); thread.Start(); } void ShowDot() { for (int i = 0; i < 100; i++) { this.Invoke((() => { txtValue.Text += "."; })); System.Threading.Thread.Sleep(10); } }

通过在线程函数中调用Thread.Sleep()暂停当前线程,使线程进入休眠状态。此时线程会占用尽可能少的CPU时间。

线程等待

假设有线程t,在主程序中调用了t.Join()方法,该方法允许我们等待直到线程t完成。当线程t完成 时,主程序会继续运行。借助该技术可以实现在两个线程间同步执行步骤。第一个线程会等待另一个线程完成后再继续执行。第一个线程等待时是处于阻塞状态(正如暂停线程中调用 Thread.Sleep方法一样)

C#
private void btnStart_Click(object sender, EventArgs e) { Thread thread = new Thread(ShowDot); thread.Start(); thread.Join(); Thread thread1 = new Thread(ShowDot1); thread1.Start(); } void ShowDot() { for (int i = 0; i < 100; i++) { this.BeginInvoke((() => { txtValue.Text += "."; })); System.Threading.Thread.Sleep(10); } } void ShowDot1() { for (int i = 0; i < 100; i++) { this.BeginInvoke((() => { txtValue1.Text += "."; })); System.Threading.Thread.Sleep(10); } }

image.png

终止线程

C#
private void btnStart_Click(object sender, EventArgs e) { Thread thread = new Thread(ShowDot); thread.Start(); // SpinWait 不仅仅只是空循环。谨慎实现后,它可以提供适用于一般情况的正确旋转行为, // 并且本身能够在旋转时间够长(大致是内核转换所需的时间长度)时自行启动上下文切换。 //有点像Sleep SpinWait.SpinUntil(() => false, 100); thread.Interrupt(); } void ShowDot() { for (int i = 0; i < 100; i++) { this.BeginInvoke((() => { txtValue.Text += "."; })); System.Threading.Thread.Sleep(10); } }

thread.Abort(); 这个在.Net中不支持了,只在.Net Framework中支持。

注意

在多线程编程中,正确管理线程的生命周期是非常重要的。不当的线程管理可能会导致资源泄露、死锁或其他并发问题。因此,建议使用高级的并发和同步机制,如任务并行库(TPL)中的Task类,它提供了更加丰富和灵活的控制方式。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!