Thread.Sleep(int i):将当前线程阻塞(暂停)指定的毫秒数,并使线程处于WaitSleepJoin状态。可以通过Thread.Interrupt()来唤醒它。
Thread.Suspend():挂起(睡眠)线程,或者如果线程已挂起,则不起作用。如果不使用Thread.Resume()来唤醒它,则线程被永久的挂起。
Thread.Join():阻塞(暂停)调用线程,直到某个线程终止时为止。常和Thread.Abort一起使用,保证线程被顺利结束。
Thread.Abort():终止当前线程的执行,在线程上调用此方法时,系统在此线程中引发 ThreadAbortException 以中止它。ThreadAbortException 是一个可以由应用程序代码捕获的特殊异常,但除非调用 ResetAbort,否则会在 catch 块的结尾再次引发它。ResetAbort 取消要中止的请求,并阻止 ThreadAbortException 终止此线程。未执行的 finally 块将在线程终止前执行。
为什么线程结束前要抛出一个异常呢?为什么即使已捕获到该异常,但在 catch 块的结尾会再次被运行库引发呢?为什么必须调用ResetAbort()来取消终止请求呢?看下面的例子:
using System;
using System.Threading;
using System.Security.Permissions;
public class ThreadWork
{
public static void DoWork()
{
try
{
for(int i=0; i<100; i++)
{
Console.WriteLine("Thread - working.";
Thread.Sleep(100);
}
}
catch(ThreadAbortException e)
{
Console.WriteLine("Thread - caught ThreadAbortException - resetting.";
Console.WriteLine("Exception message: {0}", e.Message);
Thread.ResetAbort();
}
finally
{
Console.WriteLine("Thread - still alive and working.";
Thread.Sleep(1000);
Console.WriteLine("Thread - finished working.";
}
}
}
class ThreadAbortTest
{
public static void Main()
{
ThreadStart myThreadDelegate = new ThreadStart(ThreadWork.DoWork);
Thread myThread = new Thread(myThreadDelegate);
myThread.Start();
Thread.Sleep(100);
Console.WriteLine("Main - aborting my thread.";
myThread.Abort();
myThread.Join();
Console.WriteLine("Main ending.";
}
}
看完上面的例子,结合自己的经验,我假设一个场景,假如现在是开发一个网络监听的应用程序,肯定要用一个回调函数来监听某端口,此时在回调函数中肯定有一个死循环在做这个工作,因此,该监听线程永远也无法执行结束。但是一般我们都是在关闭用户界面的时候结束该前台线程的啊,对,在关闭用户界面的时候,此时可以在主线程中调用Thread对象的Abort方法,该方法会终止该子线程的执行,并抛出一个ThreadAbortException 异常,如果用户没有做异常处理,则CLR采用默认方式捕获到异常后,会结束线程的执行。想一下,为什么CLR不直接为我们结束线程,而要抛出一个异常,然后再自己捕获到该异常后,主动结束呢?因为.NET要让我们程序员在线程结束之前作一些善后工作,比如关闭在线程中打开的套接字等外部资源。当然,你不做也不会有什么运行错误,不过,.NET都为我们想得那么周到,如果你的程序使用了数据库连接等外部资源,何不用该异常处理的方式将其关掉呢,因此,你可以采用finally块,在该块中释放资源。那如果还用上了catch块,为什么要在catch块结束处用上ResetAbort这个函数呢?如果不用会有什么结果?如果不用这个函数的话,在catch结束后,系统会再次引发ThreadAbortException 异常,当然,这个异常就不是给你用的了,这是告诉CLR,你已经关闭了外部资源,现在可以结束线程了,呵呵,之后CLR随时会把线程咔嚓掉,你想想,如果不在catch后用上ResetAbort,finally里头的代码就有可能还未执行完毕,线程就被结束了,外部资源可能也未被释放,这不是我们想要的结果。因此,在catch块末尾用ResetAbort取消第下一次抛出异常,当然,CLR就不会再收到立即结束线程的异常,线程也就不会被结束掉,它会在finally块执行完成后,自动结束。因此,在finally中如果还有大量的操作要做的话,线程也有可能等一段时间才能结束掉,或者永远都不会被结束(又一个死循环)。
总结起来,基本结构如下:
如果没有外部资源可释放的话,这个异常就没有必要捕获,因此,下面的结构是针对有外部资源使用的线程而言的。
try
{
//这里做线程操作
}
catch(ThreadAbortException e)
{
//其他工作
Thread.ResetAbort();//这句代码可选,如果catch块后还有代码要执行的时候才用,比如finally。
}
finally
{
//释放外部资源等等...
}
正文
Thread 类实例方法总结 [原]2006-05-26 10:55:00
【评论】 【打印】 【字体:大 中 小】 本文链接:http://blog.pfan.cn/Csharpsky/14883.html
阅读(8355) | 评论(3)
版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!
评论