zoukankan      html  css  js  c++  java
  • 如何优雅地控制线程状态

    为了控制线程状态,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

  • 相关阅读:
    2016年 CodePen 最热门的前端代码 Top 100
    HttpClientHelper
    .net core mvc 简易登录
    senparc 第三方授权回调,保存授权信息到文件
    盛派微信Sdk .Net Core 初始化注册服务信息
    分享一个gif截图工具
    C# 单例模式
    获取微信AccessToken,保存在内存中,过期后重新获取
    .NET Core WebAPI Swagger使用
    .net Core 读取配置文件参数
  • 原文地址:https://www.cnblogs.com/ice-/p/4244944.html
Copyright © 2011-2022 走看看