如何优雅地控制线程状态

来源:互联网 发布:东风标致3008数据 编辑:程序博客网 时间:2024/04/30 16:11

为了控制线程状态,Thread类中提供了Suspend,Resume,Abort等方法。但Suspend和Resume方法已被MS标注为已过时(Obsolete),若是简单的为线程设置一些状态量,又会牵扯出跨线程访问的问题,所以要寻求新的更优的解决方案。在论坛上上看到一篇文章,同时介绍了工作线程在线程池中时的控制方法,很不错。代码注释很全面,一看便懂。

class Program    {        static void Main(string[] args)        {            UseThreadAPI();            UseSyncEvent();            UseThreadPool();            UseSyncEventThreadPool();            Console.WriteLine("All tests  finished");            Console.ReadKey();        }        /// <summary>        /// 使用标准Thread API来控制线程状态,        /// Suspend和Resume是过时的方法,MS不推荐使用        /// MS推荐的方式就是后面要提到的使用Monitor,Event等做同步控制.        /// </summary>        static void UseThreadAPI()        {            Console.WriteLine("----------Use thread API----------");            Thread t = new Thread(                new ThreadStart(() =>                {                    while (true)                    {                        Console.WriteLine("Now Date:{0}", DateTime.Now);                        Thread.Sleep(1000);                    }                }                ));            t.Start();            //暂停线程执行            Console.ReadKey();            t.Suspend();            Console.WriteLine("Thread suspended");            //继续线程执行            Console.ReadKey();            t.Resume();            Console.WriteLine("Thread resumed");            //结束线程            Console.ReadKey();            t.Abort();            Console.WriteLine("Thread aborted");            Console.ReadKey();        }        /// <summary>        /// 使用Event做同步控制        /// 三个Event组合使用就可以产生同Suspend,Resuem,Abort相同的效果        /// 而且你可以控制Abort的时机以及并作出适当的处理        /// 而不是像Thread.Abort一样通过异常的方式结束线程        /// </summary>        static void UseSyncEvent()        {            Console.WriteLine("----------Use  sync event----------");            AutoResetEvent evtPause = new AutoResetEvent(false);            AutoResetEvent evtResume = new AutoResetEvent(false);            AutoResetEvent evtStop = new AutoResetEvent(false);            Thread t = new Thread(                new ThreadStart(() =>                {                    //WaitOne(1000),可产生Sleep(1000)相同的效果                    //如果eveStop被置位,则立即返回True,跳出循环                    //如果等待1000ms超时,则返回False,继续循环                    while (!evtStop.WaitOne(1000))                    {                        //WaitOne(0)可立即判断evtPase有没有被置位                        //如果置位,进入暂停状态,等待Resume被置位才会恢复线程执行                        if (evtPause.WaitOne(0))                        {                            //WaitOne()不带参数表示一直等待,直到被置位                            evtResume.WaitOne();                        }                        Console.WriteLine("Now Date:{0}", DateTime.Now);                    }                }                ));            t.Start();            //暂停线程执行            Console.ReadKey();            evtPause.Set();            Console.WriteLine("Thread suspended");            //继续线程执行            Console.ReadKey();            evtResume.Set();            Console.WriteLine("Thread resumed");            //结束线程            Console.ReadKey();            evtStop.Set();            Console.WriteLine("Thread stopped");            Console.ReadKey();        }        class ThreadStatusController        {            /// <summary>            /// 声明为volatile可以避免用lock进行加锁同步            /// 编译器自己会做优化            /// 另外不能声明属性为volatile,因此只能作为成员变量放出.            /// </summary>            public volatile bool IsPauseRequired;            public volatile bool IsStopRequired;        }        /// <summary>        /// 对于放入线程池的进程,是无法通过Thread的API进行控制的        /// 通常的做法是通过一些bool量做控制,这不是优雅的解决方案.        /// </summary>        static void UseThreadPool()        {            Console.WriteLine("----------Use thread pool----------");            var tsc = new ThreadStatusController();            ThreadPool.QueueUserWorkItem(status =>            {                var ctrl = status as ThreadStatusController;                //等待IsStopRequired标志量的值为True                while (!ctrl.IsStopRequired)                {                    //如果不是Pause请求,则执行                    if (!ctrl.IsPauseRequired)                        Console.WriteLine("Now Date:{0}", DateTime.Now);                    Thread.Sleep(1000);                }                        }, tsc);            //暂停线程执行            Console.ReadKey();            tsc.IsPauseRequired = true;            Console.WriteLine("Thread suspended");            //继续线程执行            Console.ReadKey();            tsc.IsPauseRequired = false;            Console.WriteLine("Thread resumed");            //结束线程            Console.ReadKey();            tsc.IsStopRequired = true;            Console.WriteLine("Thread aborted");            Console.ReadKey();        }        /// <summary>        /// 声明三个同步事件分别对应三种同步状态        /// </summary>        class ThreadStatusEventController        {            public ThreadStatusEventController()            {                PauseEvent = new AutoResetEvent(false);                ResumeEvent = new AutoResetEvent(false);                StopEvent = new AutoResetEvent(false);            }            public AutoResetEvent PauseEvent { get; set; }            public AutoResetEvent ResumeEvent { get; set; }            public AutoResetEvent StopEvent { get; set; }        }        static void UseSyncEventThreadPool()        {            Console.WriteLine("----------Use sync event with thread pool----------");            var tsc = new ThreadStatusEventController();            ThreadPool.QueueUserWorkItem(status =>            {                var ctrl = status as ThreadStatusEventController;                //控制代码跟采用Thread的方式类似,不累述                while (!ctrl.StopEvent.WaitOne(1000))                {                    if (ctrl.PauseEvent.WaitOne(0))                    {                        ctrl.ResumeEvent.WaitOne();                    }                    Console.WriteLine("Now Date:{0}", DateTime.Now);                }            }, tsc);            //暂停线程执行            Console.ReadKey();            tsc.PauseEvent.Set();            Console.WriteLine("Thread suspended");            //继续线程执行            Console.ReadKey();            tsc.ResumeEvent.Set();            Console.WriteLine("Thread resumed");            //结束线程            Console.ReadKey();            tsc.StopEvent.Set();            Console.WriteLine("Thread aborted");            Console.ReadKey();        }        }

文章来源:http://www.cnblogs.com/bloodish/archive/2011/03/21/1990025.html

0 0
原创粉丝点击