当前位置 > 首页 > Asp.net

[.Net线程处理系列]专题二:线程池中的工作者线程

2012-7-18 19:12:00来源:Asp.net

目录:

一、上节补充

二、CLR线程池基础

三、通过线程池的工作者线程实现异步

四、使用委托实现异步

五、任务

 

一、上节补充

 

对于Thread类还有几个常用方法需要说明的。

1.1 Suspend和Resume方法

这两个方法在.net Framework 1.0的时候就支持的方法,他们分别可以挂起线程和恢复挂起的线程。但在.net Framework 2.0以后的版本中这两个方法都过时了,MSDN的解释是这样:

警告:

不要使用 Suspend 和 Resume 方法来同步线程的活动。您无法知道挂起线程时它正在执行什么代码。如果您在安全权限评估期间挂起持有锁的线程,则 AppDomain中的其他线程可能被阻止。如果您在线程正在执行类构造函数时挂起它,则 AppDomain中尝试使用该类的其他线程将被阻止。这样很容易发生死锁。

对于这个解释可能有点抽象吧,让我们来看看一段代码可能会清晰点:

 

 class Program    {        static void Main(string[] args)        {            // 创建一个线程来测试            Thread thread1 = new Thread(TestMethod);                  thread1.Name = "Thread1";               thread1.Start();                Thread.Sleep(2000);            Console.WriteLine("Main Thread is running");            ////int b = 0;            ////int a = 3 / b;            ////Console.WriteLine(a);            thread1.Resume();                 Console.Read();        }        static void TestMethod()        {                 Console.WriteLine("Thread: {0} has been suspended!", Thread.CurrentThread.Name);                  //将当前线程挂起            Thread.CurrentThread.Suspend();                      Console.WriteLine("Thread: {0} has been resumed!", Thread.CurrentThread.Name);        }    }

在上面这段代码中thread1线程是在主线程中恢复的,但当主线程发生异常时,这时候就thread1一直处于挂起状态,此时thread1所使用的资源就不能释放(除非强制终止进程),当另外线程需要使用这快资源的时候, 这时候就很可能发生死锁现象。

上面一段代码还存在一个隐患,请看下面一小段代码:

 

 class Program    {        static void Main(string[] args)        {            // 创建一个线程来测试            Thread thread1 = new Thread(TestMethod);                  thread1.Name = "Thread1";               thread1.Start();            Console.WriteLine("Main Thread is running");            thread1.Resume();                 Console.Read();        }        private static void TestMethod()        {                 Console.WriteLine("Thread: {0} has been suspended!", Thread.CurrentThread.Name);            Thread.Sleep(1000);            //将当前线程挂起            Thread.CurrentThread.Suspend();                      Console.WriteLine("Thread: {0} has been resumed!", Thread.CurrentThread.Name);        }    }

当主线程跑(运行)的太快,做完自己的事情去唤醒thread1时,此时thread1还没有挂起而起唤醒thread1,此时就会出现异常了。并且上面使用的Suspend和Resume方法,编译器已经出现警告了,提示这两个方法已经过时, 所以在我们平时使用中应该尽量避免。

1.2 Abort和 Interrupt方法

Abort方法和Interrupt都是用来终止线程的,但是两者还是有区别的。

1、他们抛出的异常不一样,Abort 方法抛出的异常是ThreadAbortException, Interrupt抛出的异常为ThreadInterruptedException