如何暂停和终止线程
你能看到这篇文章,说明你已经知道如何创建线程了,因此,这里就不说明线程的创建了,详细说一下线程的暂停和终止。
我们首先了解一下,什么是前台线程和后台线程。
.Net的公用语言运行时(CLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。
对于如何暂停和继续线程的运行,在.net2.0之后,Suspend 、Resume 这两种方法都已停止使用,MS官方推荐使用标记判断的方式来处理线程的暂停与继续。
对于线程的终止,在该线程处理完该线程的指定任务,退出该线程执行任务的函数后,线程状态将改变为"Stopped",然后分别依前台线程和后台线程的区别,在应用程序退出时线程会自动结束。因此,如果我们想使某个线程停止执行,就使该线程所执行的函数执行完毕就可以了。
在使用多线程处理任务时,如果线程间的同步对象不是原子数值,而是类等引用类型,如果线程有写入的情况,则必须保证某一时刻只有一个线程能够写入,这就需要线程互斥,一般情况下,使用lock关键词处理。
互斥与同步
互斥和同步是两个紧密相关而又容易混淆的概念。
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源,如“第一类读写者模型”。
关于线程同步,可以看这篇文章:http://www.cnblogs.com/michaelxu/archive/2008/09/20/1293716.html
对于在线程调用的方法中向外传递数据,使用事件向执行该方法的对象传递需要发送出的数据。
下面,是我测试的代码:
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Threading;
5
6 namespace ThreadTest
7 {
8 class Program
9 {
10 static void Main(string[] args)
11 {
12 try
13 {
14 Thread[] ts = new Thread[2];
15 ABC[] arr = new ABC[2];
16 ABC info;
17 for (int i = 0; i < ts.Length; ++i)
18 {
19 info = new ABC();
20 info.IsStop = false;
21 arr[i] = info;
22 ts[i] = new Thread(new ParameterizedThreadStart(info.Run));
23 ts[i].Name = string.Format("thread__{0}", i);
24 ts[i].IsBackground = true;
25 }
26 Thread.Sleep(1000);
27 for (int i = 0; i < ts.Length; ++i)
28 {
29 ts[i].Start();
30 }
31 Thread.Sleep(2000);
32 for (int i = 0; i < arr.Length; ++i)
33 {
34 arr[i].IsStop = true;
35 }
36 Thread.Sleep(5000);
37 for (int i = 0; i < ts.Length; ++i)
38 {
39 Console.WriteLine("{0}__{1}", ts[i].Name, ts[i].ThreadState);
40 }
41 Thread.Sleep(5000);
42 for (int i = 0; i < ts.Length; ++i)
43 {
44 Console.WriteLine("{0}__{1}", ts[i].Name, ts[i].ThreadState);
45 ts[i].Abort();
46 }
47 Thread.Sleep(5000);
48 for (int i = 0; i < ts.Length; ++i)
49 {
50 Console.WriteLine("{0}__{1}", ts[i].Name, ts[i].ThreadState);
51 }
52 Console.WriteLine("...");
53 }
54 catch (Exception ex)
55 {
56 Console.WriteLine(ex.Message);
57 }
58 }
59
60 class ABC
61 {
62 int start = 0;
63 int end = 0;
64
65 public bool IsStop
66 {
67 get;
68 set;
69 }
70
71 public ABC()
72 {
73 int a = new Random((int)DateTime.Now.Ticks).Next(0, 50);
74 int b = new Random((int)DateTime.Now.Ticks).Next(51, 100);
75 start = Math.Min(a, b);
76 end = Math.Max(a, b);
77 }
78
79 public void Run(object o)
80 {
81 Console.WriteLine();
82 Console.WriteLine("start {0}__{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
83 Console.WriteLine();
84 for (int i = start; i <= end; ++i)
85 {
86 Console.Write(i);
87 }
88 Console.WriteLine();
89 Console.WriteLine("isRun {0}__{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
90
91 while (true)
92 {
93 if (!IsStop)
94 {
95 //在此处执行具体操作
96 Thread.Sleep(1);
97 continue;
98 }
99 else
100 {
101 break;
102 }
103 }
104 Console.WriteLine("end {0}__{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
105 }
106 }
107 }
108 }
109
这是执行结果:
如上图可见,线程执行时,其状态值为Background,当线程执行完成后,其状态值为Stopped.
以上是以后台线程为例。