通过提供一个委托来启动线程,该委托表示线程在其类构造函数中执行的方法。 然后调用 Start 方法以开始执行。
构造函数可以使用两种委托类型之一,具体取决于是否可以将参数 Thread 传递给要执行的方法:
如果方法没有参数,则向 ThreadStart 构造函数传递委托。 它具有签名:
public delegate void ThreadStart()
如果方法具有参数,则向 ParameterizedThreadStart 构造函数传递委托。 它具有签名:
public delegate void ParameterizedThreadStart(object obj)
在C#中创建线程时,首先需要创建一个Thread委托实例,再以这个TreadStart委托作为参数,来构造Thread实例。
Thread类拥有四种重载的构造函数:
| Thread(ParameterizedThreadStart) | 初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托。 |
| Thread(ThreadStart) | 初始化 Thread 类的新实例。 |
| Thread(ParameterizedThreadStart, Int32) | 初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托,并指定线程的最大堆栈大小。 |
| Thread(ThreadStart, Int32) | 初始化 Thread 类的新实例,指定线程的最大堆栈大小。 |
注意:线程不会在创建时开始执行。 若要计划线程的执行,请调用 Start 方法。 若要将数据对象传递给线程,请使用 Start(Object) 方法重载。
备注:如果线程已经终止,则无法通过再次调用Start方法来重启线程。
1、Thread(ParameterizedThreadStart)
- 初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托。
- //未使用命名空间时,使用方法
- public Thread (System.Threading.ParameterizedThreadStart start);
-
- //使用了命名空间时,使用方法
- using System.Threading;
- public Thread (ParameterizedThreadStart start);
案例:
- using System;
- using System.Threading;
-
- public class Work
- {
- public static void Main()
- {
- // 启动一个调用参数化静态方法的线程。
- Thread newThread = new Thread(Work.DoWork);
- newThread.Start(42);
-
- // 启动一个调用参数化实例方法的线程。
- Work w = new Work();
- newThread = new Thread(w.DoMoreWork);
- newThread.Start("The answer.");
- }
-
- public static void DoWork(object data)
- {
- Console.WriteLine("静态方法!. Data='{0}'",data);
- }
-
- public void DoMoreWork(object data)
- {
- Console.WriteLine("实例方法!. Data='{0}'",data);
- }
- }
2、Thread(ThreadStart)
- //未使用命名空间
- public Thread (System.Threading.ThreadStart start);
-
- //使用了命名空间
- using System.Threading;
- public Thread (ThreadStart start);
举例:创建执行静态方法的线程:
- using System;
- using System.Threading;
-
- class Test
- {
- static void Main()
- {
- Thread Nt1 =new Thread(new ThreadStart(Work.DoWork));
- Nt1.Start();
- }
- }
-
- class Work
- {
- public static void DoWork()
- {
- Console.WriteLine("新的线程启动(静态方法)");
- }
- }
举例:创建执行实例方法的线程:
- using System;
- using System.Threading;
-
- class Test
- {
- static void Main()
- {
- Work Nw1 = new Work();
- Thread Nt1 =new Thread(new ThreadStart(Nw1.DoWork));
- Nt1.Start();
- }
- }
-
- class Work
- {
- public void DoWork()
- {
- Console.WriteLine("新的线程启动(实例方法)");
- }
- }
找错误案例:

正确修改为:
- using System;
- using System.Threading;
-
- class Test
- {
- static void Main()
- {
- Test x1 = new Test();
- Thread x2 = new Thread(new ThreadStart(x1.DoWork));
- x2.Start();
- }
-
- public void DoWork()
- {
- Console.WriteLine("新的线程启动(实例方法)");
- }
- }
3、Thread(ParameterizedThreadStart, Int32)
4、Thread(ThreadStart, Int32)
线程的休眠是通过Thread类的Sleep方法实现的,而Thread类的实例的IsAlive属性可以判断线程是否执行完毕。
Sleep方法有两种重载方式:
| Sleep(Int32) | 将当前线程挂起指定的毫秒数。 |
| Sleep(TimeSpan) | 将当前线程挂起指定的时间。 |
注意:不要在主线程使用!
1、Sleep(Int32):将当前线程挂起指定毫秒数,C#语法格式如下:
public static void Sleep (int millisecondsTimeout);
millisecondsTimeout:Int32,挂起线程的毫秒数。 如果 millisecondsTimeout 参数的值为零,则该线程会将其时间片的剩余部分让给任何已经准备好运行的、具有同等优先级的线程。 如果没有其他已经准备好运行的、具有同等优先级的线程,则不会挂起当前线程的执行。
- using System;
- using System.Threading;
-
- class Example
- {
- static void Main()
- {
- for (int i = 0; i < 5; i++)
- {
- Console.WriteLine("休眠 2 秒.");
- Thread.Sleep(2000);
- }
-
- Console.WriteLine("Main thread exits.");
- }
- }
2、Sleep(TimeSpan):将当前线程挂起指定的时间,语法格式如下:
public static void Sleep (TimeSpan timeout);
timeout:挂起线程的时间量。 如果 timeout 参数的值为零,则该线程会将其时间片的剩余部分让给任何已经准备好运行的、具有同等优先级的线程。 如果没有其他已经准备好运行的、具有同等优先级的线程,则不会挂起当前线程的执行。
- 将当前线程挂起指定的时间:多少小时,多少分钟,多少秒
- public TimeSpan(int hours, int minutes, int seconds);
- using System;
- using System.Threading;
-
- class Example
- {
- static void Main()
- {
- TimeSpan interval = new TimeSpan(0, 0, 2);//0小时0分钟2秒
-
- for (int i = 0; i < 5; i++)
- {
- Console.WriteLine("Sleep for 2 seconds.");
- Thread.Sleep(interval);
- }
-
- Console.WriteLine("Main thread exits.");
- }
- }
当一个线程执行时间太长时,用户有可能要终止这个线程,这个就要使用Abort方法。该方法有两种重载方式:
| Abort() | 在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。 |
| Abort(Object) | 引发在其上调用的线程中的 ThreadAbortException 以开始处理终止线程,同时提供有关线程终止的异常信息。 调用此方法通常会终止线程。 |
备注:线程的Abort方法用于永久地停止托管线程。在调用Abort方法时,公共语言运行库在目标线程中引发ThreadAbortException异常,目标线程可捕捉此异常。一旦线程终止,将无法重新启动。
- 在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。
- public void Abort ();
-
-
- 引发在其上调用的线程中的 ThreadAbortException 以开始处理终止线程,同时提供有关线程终止的异常信息。 调用此方法通常会终止线程。
- public void Abort(Object stateInfo)
- stateInfo:一个对象,它包含应用程序特定的信息(如状态),该信息可供正被中止的线程使用。
- using System;
- using System.Threading;
-
- class Test
- {
- public static void Main()
- {
- Thread newThread = new Thread(new ThreadStart(TestMethod));
- newThread.Start();
- Thread.Sleep(1000);
-
- // Abort newThread.
- Console.WriteLine("Main aborting new thread.");
- newThread.Abort("Information from Main.");
-
- // Wait for the thread to terminate.
- newThread.Join();
- Console.WriteLine("New thread terminated - Main exiting.");
- }
-
- static void TestMethod()
- {
- try
- {
- while (true)
- {
- Console.WriteLine("New thread running.");
- Thread.Sleep(1000);
- }
- }
- catch (ThreadAbortException abortException)
- {
- Console.WriteLine((string)abortException.ExceptionState);
- }
- }
- }
Join方法用来阻塞调用线程,直到某个线程终止为止。该方法有三种重载形式:
| Join() | 在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止。 |
| Join(Int32) | 在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止或经过了指定时间为止。 |
| Join(TimeSpan) | 在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止或经过了指定时间为止。 |
备注:如果在程序中使用了多线程,辅助线程还没有执行完毕,那么在关闭窗体时,必须要关闭辅助线程,否则会引发异常。
① Join()
- 在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止。
-
- public void Join ();
-
- Join 是一种同步方法,它阻止调用 (线程,即调用方法的线程) 调用方法的线程 Join 完成。
- 使用此方法可确保线程已终止。
- 如果线程未终止,调用方将无限期阻止。
- 在下面的示例中,线程调用 的 方法 Thread1 Join() Thread2 ,这会导致 Thread1 在 Thread2 完成后阻止。
- using System;
- using System.Threading;
-
- public class Example
- {
- static Thread thread1, thread2;
-
- public static void Main()
- {
- thread1 = new Thread(ThreadProc);
- thread1.Name = "Thread1";
- thread1.Start();
-
- thread2 = new Thread(ThreadProc);
- thread2.Name = "Thread2";
- thread2.Start();
- }
-
- private static void ThreadProc()
- {
- Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
- if (Thread.CurrentThread.Name == "Thread1" &&
- thread2.ThreadState != ThreadState.Unstarted)
- thread2.Join();
-
- Thread.Sleep(4000);
- Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
- Console.WriteLine("Thread1: {0}", thread1.ThreadState);
- Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
- }
- }
时线程已终止 Join ,则该方法将立即返回 。
②Join(Int32)
- 在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止或经过了指定时间为止。
-
- public bool Join (int millisecondsTimeout);
-
- 参数:millisecondsTimeout—等待线程终止的毫秒数。
- 如果线程已终止,则为 true;如果 false 参数指定的时间量已过之后还未终止线程,则为 millisecondsTimeout。
- using System;
- using System.Threading;
-
- public class Example
- {
- static Thread thread1, thread2;
-
- public static void Main()
- {
- thread1 = new Thread(ThreadProc);
- thread1.Name = "Thread1";
- thread1.Start();
-
- thread2 = new Thread(ThreadProc);
- thread2.Name = "Thread2";
- thread2.Start();
- }
-
- private static void ThreadProc()
- {
- Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
- if (Thread.CurrentThread.Name == "Thread1" &&
- thread2.ThreadState != ThreadState.Unstarted)
- if (thread2.Join(2000))
- Console.WriteLine("Thread2 has termminated.");
- else
- Console.WriteLine("The timeout has elapsed and Thread1 will resume.");
-
- Thread.Sleep(4000);
- Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
- Console.WriteLine("Thread1: {0}", thread1.ThreadState);
- Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
- }
- }
③Join(TimeSpan)
- 在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止或经过了指定时间为止。
-
- public bool Join (TimeSpan timeout);
-
- timeout:设置等待线程终止的时间量的TimeSpan。
- 如果线程已终止,则为 true;如果 false 参数指定的时间量已过之后还未终止线程,则为 timeout。
- //下面的代码示例演示如何将 值 TimeSpan 与 方法 Join 一起使用。
- using System;
- using System.Threading;
-
- class Test
- {
- static TimeSpan waitTime = new TimeSpan(0, 0, 1);
-
- public static void Main()
- {
- Thread newThread = new Thread(Work);
- newThread.Start();
-
- if(newThread.Join(waitTime + waitTime)) {
- Console.WriteLine("New thread terminated.");
- }
- else {
- Console.WriteLine("Join timed out.");
- }
- }
-
- static void Work()
- {
- Thread.Sleep(waitTime);
- }
- }
备注:Join(TimeSpan) 是一种同步方法,它阻止调用线程 (,即调用方法) 直到调用方法的线程已完成或已过时间间隔 Join 。
- //下面的示例中,线程调用 的 方法,这会导致 阻塞,直到已完成或 Thread1 Join() Thread2 Thread1 Thread2 2 秒已过。
- using System;
- using System.Threading;
-
- public class Example
- {
- static Thread thread1, thread2;
-
- public static void Main()
- {
- thread1 = new Thread(ThreadProc);
- thread1.Name = "Thread1";
- thread1.Start();
-
- thread2 = new Thread(ThreadProc);
- thread2.Name = "Thread2";
- thread2.Start();
- }
-
- private static void ThreadProc()
- {
- Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
- if (Thread.CurrentThread.Name == "Thread1" &&
- thread2.ThreadState != ThreadState.Unstarted)
- if (thread2.Join(TimeSpan.FromSeconds(2)))
- Console.WriteLine("Thread2 has termminated.");
- else
- Console.WriteLine("The timeout has elapsed and Thread1 will resume.");
-
- Thread.Sleep(4000);
- Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
- Console.WriteLine("Thread1: {0}", thread1.ThreadState);
- Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
- }
- }
如果 Timeout.Infinite 为 指定了 ,则此方法的行为与方法重载相同, timeout 返回值 Join() 除外。
如果调用 时线程已终止 Join ,则该方法将立即返回 。
此方法更改当前线程的状态以包括 WaitSleepJoin 。 不能对 Join 状态为 的线程 ThreadState.Unstarted 调用 。
Suspend方法用于挂起线程,Resume方法用于继续执行已经挂起的线程。可以使用这两个方法进行线程的同步,和Start方法有些类似的是:在调用Suspend方法后不会立即停止,而是执行到一个安全点后挂起。
1、Suspend方法
挂起线程,或者如果线程已挂起,则不起作用。语法格式为:
public void Suspend();
2、Resume方法
继续已挂起的线程。语法格式为:
public void Resumne();