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 }