C#多线程学习之Thread
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading; 6 7 namespace ThreadTest 8 { 9 class Program 10 { 11 static void DoWork() 12 { 13 Console.WriteLine("DoWork is begin"); 14 15 for (int i = 0; i < 10; i++) 16 { 17 try 18 { 19 if (i == 7) 20 { 21 //终止线程,会抛出一个ThreadAbortException 类型的异常 22 Thread.CurrentThread.Abort(i); 23 } 24 25 Console.WriteLine(string.Format("{0} {1}", Thread.CurrentThread.Name, i)); 26 Thread.Sleep(300); 27 } 28 catch (ThreadAbortException e) 29 { 30 Console.WriteLine(string.Format("{0} is Abort when i is {1}", Thread.CurrentThread.Name, e.ExceptionState)); 31 32 //取消终止,静态方法 33 Thread.ResetAbort(); 34 } 35 36 } 37 38 Console.WriteLine("DoWork is end"); 39 } 40 41 /// <summary> 42 /// 43 /// </summary> 44 /// <param name="args"></param> 45 static void Main(string[] args) 46 { 47 Console.WriteLine("Main thread begin"); 48 49 50 #region Thread类构造函数的参数是:不带参数的静态方法 51 52 Thread myThread1 = new Thread(Program.DoWork); 53 myThread1.Name = "thread1"; 54 55 /* 56 * 有关前台线程和后台线程 57 * 线程Thread有一个属性IsBackground,通过把此属性设置为true,就可以把线程设置为后台线程! 58 * 当一个进程除了主线程之外其他线程都是后台线程时,应用程序域将在主线程完成时就被卸载,而不会等待异步线程的运行。 59 * 使用Thread.Start()启动的线程默认为前台线程,而系统必须等待所有前台线程运行结束后,应用程序域才会自动卸载。 60 */ 61 62 //设置为后台线程 63 myThread1.IsBackground = true; 64 65 myThread1.Start(); 66 67 #endregion 68 69 70 71 #region Thread类构造函数的参数是:带参数的非静态方法 72 73 string str = string.Format("test"); 74 Test myTest = new Test(); 75 76 //如果Thread的构造函数的参数是带参数的方法,则这个参数要求是object类型 77 Thread myThread2 = new Thread(myTest.ShowMessage); 78 myThread2.Name = "thread2"; 79 80 //设置为前台线程,默认为前台线程 81 myThread2.IsBackground = false; 82 83 myThread2.Start(str); 84 85 86 /* 87 * thread线程间的同步:join方法 88 * 89 * 关于对 Thread类实例的Join方法的理解. 90 * 两个线程的关系如下:一个线程(旧的)生成并启动另一个线程(新的). 91 * join方法只能在以下条件被调用:一个新的线程被创建并且调用start方法后. 92 * join方法的作用:阻塞。在旧的线程代码里,运行到行新线程实例的join方法时,旧线程将会被阻塞, 93 * 直到新线程(不管是前台还是后台线程)执行完成后,旧线程才会继续执行join方法后面的代码。 94 * 95 * 比喻如下:线程A创建了线程B和线程C并且都调用start方法启动了线程B和C,线程A才能调用线程B和C的join方法, 96 * 表示线程A将阻塞等到线程B和C执行完之后再继续执行。但线程B和C之间是不用通过join方法来通信或者同步的。 97 * 98 * 在本例里,main线程是主线程,创建线程myThread1和myThread2并都启动了,在执行到myThread2.Join();代码时, 99 * 主线程main线程将被阻塞,直到myThread2线程执行完之后,再继续执行 100 * 101 */ 102 103 myThread2.Join(); 104 105 106 #endregion 107 108 109 //其他:Suspend 与 Resume 方法分别表示挂起和恢复线程,已过时,微软不建议继续使用,不做介绍。 110 111 Console.WriteLine("Main thread end"); 112 Thread.Sleep(2000); 113 // Console.ReadKey(); 114 } 115 116 117 } 118 119 class Test 120 { 121 //要作为Thread的构造函数的参数,则这个参数要求是object类型 122 public void ShowMessage(object obj) 123 { 124 Console.WriteLine("ShowMessage is begin"); 125 126 string str = obj as string; 127 for (int i = 0; i < 10; i++) 128 { 129 Console.WriteLine(string.Format("{0} {1}{2}", Thread.CurrentThread.Name,str, i)); 130 Thread.Sleep(500); 131 } 132 133 Console.WriteLine("ShowMessage is end"); 134 } 135 } 136 }