博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用Interrupt让线程提前醒来

Posted on 2010-11-30 13:15  风-  阅读(681)  评论(0)    收藏  举报

先来看一下MSDN里关于Interrupt的描述:

Thread.Interrupt 方法,中断处于 WaitSleepJoin 线程状态的线程。

再来看这样一段代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace TestInterrupt
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个线程
            Thread NewThread = new Thread(new ThreadStart(Run));
            //启动这个线程
            NewThread.Start();
            //主线程等待0.5秒,确保新线程已经启动
            Thread.Sleep(500);
            //调用Interrupt
            NewThread.Interrupt();

            Console.ReadKey();
        }

        static void Run()
        {
            int i = 0;
            while (i <3)
            {
                i++;
                Console.WriteLine("线程准备第{0}次休眠,Time is:{1}.{2}", i, System.DateTime.Now, System.DateTime.Now.Millisecond);
                try
                {
                    Thread.Sleep(3000);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message.ToString());
                }
                Console.WriteLine("线程结束第{0}次休眠,Time is:{1}.{2}", i,System.DateTime.Now, System.DateTime.Now.Millisecond);
                Console.WriteLine();
            }
        }
    }
}

 

程序运行结果如图:

 

可以看出,第一次休眠时,因为新线程被执行了Interrupt方法,所以并没有经过3秒钟的休眠时间,而是进入了ThreadInterruptedException异常处理过程,而得到提前醒来的效果。第二次,第三次都休眠3秒后恢复运行。

这是一个非常好的现象,它意味着我可以在一个线程中等待某个事件发生时,并设置一个时间限制,如果事件发生了,那么执行过程可以立即得到恢复,或者在超过了这个时间限制后,继续运行下去。通过这个简单的sleep(xx)就可以实现繁杂的超时处理。

MSDN备注里还有一句话:

如果此线程当前未阻塞在等待、休眠或联接状态中,则下次开始阻塞时它将被中断。

也就是说如果你对一个处于运行状态的线程执行了Interrupt操作,那么它将会在你下次执行sleep()时,产生ThreadInterruptedException异常,而跳过休眠时间.