自己最近写的一组日志处理类(线程调度优化)

来源:互联网 发布:unity3d webplayer 编辑:程序博客网 时间:2024/06/13 10:04

前面分享的一篇文章<<自己最近写的一组日志处理类(支持高并发处理)>>里写了一个多线程的写日志的类,当时测试的时候没有太注意,后面发现这个日志类占用cpu太厉害,经过调试发现问题出在对于线程的挂起(Suspend)和唤醒(Resume)上面(这两个方法已经在新的框架里里面被废掉了).我调用这两个方法的目的就是在没有日志写的时候,线程不要再运行,等待有需要写日志的时候再继续工作.后面改了一种方式来实现这个目的,CPU占用问题就解决了,当然下面的这种方式也是对线程挂起和唤醒的一种新的替代方式,下面是修改后的代码,注释很详细,原来的代码大家请参考前面的博文:

 /// <summary>        /// 定义一个信号变量,采用的是ManualResetEvent        /// </summary>        private ManualResetEvent resumeEvent = new ManualResetEvent(false);        /// <summary>        /// 定义一个变量,用于记录线程是否处在pause状态.        /// </summary>        private volatile bool FPaused = false;        /// <summary>        /// 线程挂起        /// </summary>        public void Pause()        {            //如果当前线程不处在挂起状态就进行挂起操作            if (FPaused == false)            {                FPaused = true;                //重新设置信号量为初始状态                resumeEvent.Reset();                //进行线程等待.                resumeEvent.WaitOne();            }        }        /// <summary>        /// 唤醒线程并继续执行        /// </summary>        public void Resume()        {            //如果在运行就不进行唤醒操作            if (FPaused == true)            {                FPaused = false;                //唤醒所有等待线程,本例中等待的只有当前写线程(因此也可以用AutoResetEvent来实现).                resumeEvent.Set();            }        }        private void WriteLogToFile()        {            while (FStop==false)            {                try                {                    //_streamWriter.Flush();                    //Thread.Sleep(10000);                    string theLogContent = null;                    //队列操作时需要锁定,否则会报错.队列并不是线程安全的.                    //但多个队列可以同时写.                    lock (this)                    {                        theLogContent = _logCaches.Dequeue();                    }                    if (theLogContent != null && theLogContent != "")                    {                        _streamWriter.WriteLine(DateTime.Now.ToString() + ": " + theLogContent);                        _streamWriter.Flush();                        LastExecTime = DateTime.Now;                    }                    //修改调整处                    //如果日志缓冲区为空,则挂起当前线程.                    if (_logCaches.Count <= 0)                    {                                                this.Pause();                                            }                }                catch (Exception ex)                {                    SysAppEventWriter.WriteEvent(-1, ex.Message, System.Diagnostics.EventLogEntryType.Error);                }            }        }