c# 线程的基本使用
创建线程
线程的基本操作
线程和其它常见的类一样,有着很多属性和方法,参考下表:
创建线程的方法有很多种,这里我们先从thread开始创建线程
class Program { static void Main(string[] args) { Thread t = new Thread(PrintNumbers); t.Start(); PrintNumbers(); } static void PrintNumbers() { Console.WriteLine("Starting..."); for (int i = 0; i < 10; i++) { Console.WriteLine(i); } } }
Thread构造函数接受两种委托
public delegate void ThreadStart(); 无返回值、无参的 public delegate void ParameterizedThreadStart(object obj);无返回值、参数为object类型的方法
既然构造函数是委托那么我还可以用lambda来简写
Thread t = new Thread(()=> { Console.WriteLine("Starting..."); for (int i = 0; i < 10; i++) { Console.WriteLine(i); } }); t.Start();
很多时候我们都需要线程执行的是一个有参的方法,下面看看如何调用有多个参数的方法,
static void Main(string[] args) { int b = 10; string c = "主线程"; Thread t = new Thread(()=> PrintNumbers(b,c)); t.Start(); } static void PrintNumbers(int count,string name) { for (int i = 0; i < count; i++) { Console.WriteLine("name:{0},i:{1}",name,i); } }
Thread.Join()
我的理解是当调用Join()方法时主线程会停止工作,我不干活了,等你干完了我在继续干活如:
static void Main(string[] args) { Thread.CurrentThread.Name = "主线程"; Console.WriteLine("线程名字:{0},线程工作状态:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState); Thread abortThread = new Thread(AbortMethod); abortThread.Name = "子线程"; abortThread.Start(); abortThread.Join(); Console.WriteLine("线程名字:{0},子线程工作状态:{1}", abortThread.Name, abortThread.ThreadState); Console.WriteLine("继续干活"); Console.Read(); } private static void AbortMethod() { Console.WriteLine("线程名字:{0},子线程工作状态:{1}",Thread.CurrentThread.Name,Thread.CurrentThread.ThreadState); for (int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine(i); } }
//输出结果
线程名字:主线程,线程工作状态:Running
线程名字:子线程,子线程工作状态:Running
0
1
2
3
4
线程名字:子线程,子线程工作状态:Stopped
继续干活
Thread.Abort()
Abort()方法来终止线程的运行,我们在使用它的时候要主要,它是通过抛出ThreadAbortException异常的方式来终止线程的
static void Main(string[] args) { Thread abortThread = new Thread(AbortMethod); abortThread.Name = "test"; abortThread.Start(); Thread.Sleep(3000); try { abortThread.Abort(); } catch(Exception e) { Console.WriteLine("主线程:{0}", Thread.CurrentThread.Name); } Console.WriteLine("我被开除了,子线程:{0},子线程状态:{1}", abortThread.Name, abortThread.ThreadState); Console.Read(); } private static void AbortMethod() { try { Console.WriteLine("子线程:{0},子线程状态:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState); Console.WriteLine("开始干活"); for (int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine(i); } Console.WriteLine("继续干活"); } catch (Exception e) { Console.WriteLine("类型:"+e.GetType().Name); Console.WriteLine("子线程:{0},子线程状态:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState); } } 输出 子线程:test,子线程状态:Running 开始干活 0 1 类型:ThreadAbortException 子线程:test,子线程状态:AbortRequested 我被开除了,子线程:test,子线程状态:Aborted
从运行结果可以看出,调用Abort方法的线程引发的异常类型为ThreadAbortException, 以及异常只会在 调用Abort方法的线程中发生,而不会在主线程中抛出,并且调用Abort方法后线程的状态不是立即改变为Aborted状态,而是从AbortRequested->Aborted。
Thread.ResetAbort()
Abort方法可以通过跑出ThreadAbortException异常中止线程,而使用ResetAbort方法可以取消中止线程的操作,下面通过代码演示使用 ResetAbort方法
static void Main(string[] args) { Thread abortThread = new Thread(AbortMethod); abortThread.Name = "test"; abortThread.Start(); Thread.Sleep(1000); try { abortThread.Abort(); } catch(Exception e) { Console.WriteLine("主线程:{0}", Thread.CurrentThread.Name); } Console.WriteLine("我被开除了,子线程:{0},子线程状态:{1}", abortThread.Name, abortThread.ThreadState); Console.Read(); } private static void AbortMethod() { try { Console.WriteLine("我要被开除了"); for (int i = 0; i < 5; i++) { Thread.Sleep(1000); Console.WriteLine(i); } } catch (Exception e) { Thread.ResetAbort(); Console.WriteLine("类型:"+e.GetType().Name); Console.WriteLine("子线程:{0},子线程状态:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState); } Console.WriteLine("我又回来继续干活"); } 输出 我要被开除了 我被开除了,子线程:test,子线程状态:AbortRequested 类型:ThreadAbortException 子线程:test,子线程状态:Running 我又回来继续干活
线程的优先级
如果在应用程序中有多个线程在运行,但一些线程比另一些线程重要,这种情况下可以在一个进程中为不同的线程指定不同的优先级。线程的优先级可以通过Thread类Priority属性设置,Priority属性是一个ThreadPriority型枚举,列举了5个优先等级:AboveNormal、BelowNormal、Highest、Lowest、Normal。公共语言运行库默认是Normal类型的。见下图: