Thread 类实例方法总结

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." wink.gif
Thread.Sleep(100);
}
}
catch(ThreadAbortException e) 
{
Console.WriteLine("Thread - caught ThreadAbortException - resetting." wink.gif;
Console.WriteLine("Exception message: {0}", e.Message);
Thread.ResetAbort();
}
finally
{
Console.WriteLine("Thread - still alive and working." wink.gif
Thread.Sleep(1000);
Console.WriteLine("Thread - finished working." wink.gif;
}
}
}

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." wink.gif;
myThread.Abort();
myThread.Join();
Console.WriteLine("Main ending." wink.gif
}
}
看完上面的例子,结合自己的经验,我假设一个场景,假如现在是开发一个网络监听的应用程序,肯定要用一个回调函数来监听某端口,此时在回调函数中肯定有一个死循环在做这个工作,因此,该监听线程永远也无法执行结束。但是一般我们都是在关闭用户界面的时候结束该前台线程的啊,对,在关闭用户界面的时候,此时可以在主线程中调用Thread对象的Abort方法,该方法会终止该子线程的执行,并抛出一个ThreadAbortException 异常,如果用户没有做异常处理,则CLR采用默认方式捕获到异常后,会结束线程的执行。想一下,为什么CLR不直接为我们结束线程,而要抛出一个异常,然后再自己捕获到该异常后,主动结束呢?因为.NET要让我们程序员在线程结束之前作一些善后工作,比如关闭在线程中打开的套接字等外部资源。当然,你不做也不会有什么运行错误,不过,.NET都为我们想得那么周到,如果你的程序使用了数据库连接等外部资源,何不用该异常处理的方式将其关掉呢,因此,你可以采用finally块,在该块中释放资源。那如果还用上了catch块,为什么要在catch块结束处用上ResetAbort这个函数呢?如果不用会有什么结果?如果不用这个函数的话,在catch结束后,系统会再次引发ThreadAbortException 异常,当然,这个异常就不是给你用的了,这是告诉CLR,你已经关闭了外部资源,现在可以结束线程了,呵呵,之后CLR随时会把线程咔嚓掉,你想想,如果不在catch后用上ResetAbort,finally里头的代码就有可能还未执行完毕,线程就被结束了,外部资源可能也未被释放,这不是我们想要的结果。因此,在catch块末尾用ResetAbort取消第下一次抛出异常,当然,CLR就不会再收到立即结束线程的异常,线程也就不会被结束掉,它会在finally块执行完成后,自动结束。因此,在finally中如果还有大量的操作要做的话,线程也有可能等一段时间才能结束掉,或者永远都不会被结束(又一个死循环)。 11.gif

总结起来,基本结构如下:
如果没有外部资源可释放的话,这个异常就没有必要捕获,因此,下面的结构是针对有外部资源使用的线程而言的。
try
{
  //这里做线程操作
}
catch(ThreadAbortException e)
{
  //其他工作
  Thread.ResetAbort();//这句代码可选,如果catch块后还有代码要执行的时候才用,比如finally。
}
finally 
{
  //释放外部资源等等...
}
 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/518723/viewspace-553519/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/518723/viewspace-553519/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值