• AutoResetEvent 类的使用说明


    AutoResetEvent 类

    官方描述通知正在等待的线程已发生事件

    命名空间:System.Threading

    程序集:mscorlib

    继承于:System.Threading.WaitHandle

    AutoResetEvent从字面理解就是自动重置事件,那么它具体做什么的呢?举个例子:大家都坐过动车,要上车之前大家都要经过检票口的一道自动检票门,插入一张车票门就打开,人走过去之后门就自动关闭,保证一张车票过一个人,那么AutoResetEvent的作用就是这道自动检票门!

    简单了解了AutoResetEvent的作用后,我们来看看常用的函数:

    • AutoResetEvent(bool initialState) 构造函数,initialState参数设置门的初始状态;true 初始化开着门,就是第一个通过的人不需要票,false 初始化关着门,众生平等都要票。
    • WaitOne() 阻塞当前线程,直到接收到信号;官方说明有点错误,阻不阻塞线程取决于当前门的状态,如果门开着就不阻塞,反之则阻塞,如果初始化initialState设置为ture,那么第一次调用该函数是不会阻塞的,当然调用该函数的地方就是安装自动检票门的地方; WaitOne还提供间隔时间timeout的重载函数,作用就是在该间隔时间内没有插入票,那么门将自动打开。
    • Set() 将事件状态设置为终止状态,允许一个或多个等待线程继续;该函数就是插入票的动作,命令开门,直到一个人通过后关闭;允许多个等待线程继续的意思就是同一个AutoResetEvent实例在多处调用WaitOne函数时,Set()函数将把这些门全部打开;该函数返回一个bool类型的值,ture表示门已经成功打开,false表示门本来就是开着的什么都没发生。
    • Reset() 将事件状态设置为非终止状态,导致线程阻止;该函数是手动关闭门的命令,返回bool类型的值,ture表示门已经成功关闭,false表示门本来就是关闭的什么都没发生

    示例:使用AutoResetEvent代替Thread.Sleep实现列队异步工作,来减少获取线程的获取的时间片

    public class QueueWork<T> : IDisposable
    {
        private readonly Queue<T> _queue = new Queue<T>();
        private readonly Thread _workerThread;
        private readonly object _locker = new object();
        private readonly AutoResetEvent _waitEvent;
        private readonly Action<T> _workHandler;
    
        public QueueWork(Action<T> workHandler){
            _workerThread = new Thread(Work);
            _waitEvent = new AutoResetEvent(false);
            _workHandler = workHandler;
        }
    
        public void Add(T data){
            lock(_locker){
                _queue.Enqueue(data);
            }
            _waitEvent.Set();
        }
    
        private static void Work(){
            while (!_isDisposed)
            {
                T data;
                lock(_locker){
                    if(_queue.Count>0){
                        data = _queue.Dequeue()
                    }
                }
    
                if(data == null){
                    _waitEvent.WaitOne();
                    continue;
                }
    
                try{
                    workHandler(data);
                }catch{}
            }
        }
    
        private bool _isDisposed = false;
        public void Dispose(){
            if(!_isDisposed){
                _waitEvent.Set();
                _workerThread.Join();
                _waitEvent.Dispose();
            }
        }
    }
    
  • 相关阅读:
    函数中this指向问题及函数不同方式的调用
    拷贝继承
    组合继承
    借用构造函数
    继承
    UVA-11054(扫描法)
    hihocoder-1347 小h的树上的朋友(lca+线段树)
    UVA-10391(字符串检索)
    UVA-10125(中途相遇法)
    UVA-10827(前缀和降维)
  • 原文地址:https://www.cnblogs.com/zcylife/p/5745156.html
Copyright © 2020-2023  润新知