C# Thread.Join():等待线程执行完成(附带实例)
在 C# 程序中,假如当前程序为多线程程序且存在一个线程 A,现在需要插入线程 B,并要求线程 B 执行完毕后,继续执行线程 A,此时可以使用 Thread 类中的 Join() 方法来实现。好比 A 正在看电视,突然 B 上门收水费,A 需要付完水费后才能继续看电视。
当某个线程使用 Join() 方法加入另外一个线程时,另一个线程会等待该线程执行完毕后再执行。
Join() 方法用来阻塞调用线程,直到某个线程终止时为止,它有 3 种重载形式,下面分别介绍。
1) 在继续执行标准的 COM 和 SendMessage 消息处理期间,阻塞调用线程,直到某个线程终止为止,语法如下:
2) 在继续执行标准的 COM 和 SendMessage 消息处理期间,阻塞调用线程,直到某个线程终止或经过指定时间为止,语法如下:
3) 在继续执行标准的 COM 和 SendMessage 消息处理期间,阻塞调用线程,直到某个线程终止或经过指定时间为止,语法如下:
注意,如果在程序中使用了多线程,辅助线程还没有执行完毕,那么在关闭窗体时,必须关闭辅助线程,否则就会引发异常。
【实例】控制进度条的滚动。创建一个 Windows 窗体应用程序,默认窗体中包括两个进度条,进度条的进度由线程来控制,通过使用 Join() 方法使上面的进度条必须等待下面的进度条完成后才可以继续,主要代码如下:

图 1 两个进度条同时运行
同时运行至 20 时,上方进度条停止运行,而下方进度条继续运行,如下图所示:

图 2 上方进度条等待下方进度完成
等待下方进度条运行完成后,上方进度条继续运行,如下图所示:

图 3 上方进度条继续运行
当某个线程使用 Join() 方法加入另外一个线程时,另一个线程会等待该线程执行完毕后再执行。
Join() 方法用来阻塞调用线程,直到某个线程终止时为止,它有 3 种重载形式,下面分别介绍。
1) 在继续执行标准的 COM 和 SendMessage 消息处理期间,阻塞调用线程,直到某个线程终止为止,语法如下:
public void Join()
2) 在继续执行标准的 COM 和 SendMessage 消息处理期间,阻塞调用线程,直到某个线程终止或经过指定时间为止,语法如下:
public bool Join (int millisecondsTimeout)
- millisecondsTimeout:等待线程终止的毫秒数。
- 返回值:如果线程已终止,则为 true;如果线程在经过了 millisecondsTimeout 参数指定的时间后未终止,则为 false。
3) 在继续执行标准的 COM 和 SendMessage 消息处理期间,阻塞调用线程,直到某个线程终止或经过指定时间为止,语法如下:
public bool Join (TimeSpan timeout)
- timeout:等待线程终止的时间量的 TimeSpan。
- 返回值:如果线程已终止,则为 true;如果线程在经过了 timeout 参数指定的时间量后未终止,则为 false。
注意,如果在程序中使用了多线程,辅助线程还没有执行完毕,那么在关闭窗体时,必须关闭辅助线程,否则就会引发异常。
【实例】控制进度条的滚动。创建一个 Windows 窗体应用程序,默认窗体中包括两个进度条,进度条的进度由线程来控制,通过使用 Join() 方法使上面的进度条必须等待下面的进度条完成后才可以继续,主要代码如下:
public partial class Form1 : Form { public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; //使线程可以调用窗体控件 } Thread th1, th2; //分别控制进度条1和进度条2 void Pro1() { int count = 0; //标识何时加入线程2 while (true) { progressBar1.PerformStep(); //设置进度条的当前值 count += progressBar1.Step; //标识自增 Thread.Sleep(100); //使线程1休眠100毫秒 if (count == 20) //标识为20时,执行线程2 { th2.Join(); //使线程2调用Join方法 } } } void Pro2() { int count = 0; //标识何时执行完 while (true) { progressBar2.PerformStep(); //设置进度条的当前值 count += progressBar2.Step; //标识自增 Thread.Sleep(100); //使线程2休眠100毫秒 if (count == 100) //当count变量增长为100时 break; //跳出循环 } } private void Form1_Load(object sender, EventArgs e) { th1 = new Thread(new ThreadStart(Pro1)); //创建线程1对象 th1.Start(); //启动线程1 th2 = new Thread(new ThreadStart(Pro2)); //创建线程2对象 th2.Start(); //启动线程2 } }运行程序,两个进度条同时运行,如下图所示:

图 1 两个进度条同时运行
同时运行至 20 时,上方进度条停止运行,而下方进度条继续运行,如下图所示:

图 2 上方进度条等待下方进度完成
等待下方进度条运行完成后,上方进度条继续运行,如下图所示:

图 3 上方进度条继续运行