/// <summary>
        /// 清除空目录
        /// </summary>
        /// <param name="topDir">顶级目录</param>
        /// <param name="currentDepth">当前递归深度</param>
        /// <returns>删除目录的个数</returns>
        private int CleanEmptyDirectory(string topDir, int currentDepth)
        {
            if (currentDepth > MaxRecursiveDepth)
            {
                NLogHelper.Warn("日志文件夹存在快捷方式导致无穷递归");
                return(0);
            }

            DirectoryInfo dirInfo = new DirectoryInfo(topDir);

            if (!dirInfo.Exists)
            {
                NLogHelper.Warn($"未找到{topDir}目录,无法清理");
                return(0);
            }


            //递归子文件夹
            DirectoryInfo[] subDirs = dirInfo.GetDirectories();//返回当前目录的子目录。如果没有子目录,则此方法返回一个空数组。 此方法不是递归的。
            //非空子目录集合
            List <DirectoryInfo> nonEmptyDirList = new List <DirectoryInfo>();


            DateTime now = DateTime.Now;

            //删除目录的个数
            int delCount = 0;

            //删除空目录
            foreach (var currentDir in subDirs)
            {
                //获取存在子目录的目录
                if (currentDir.Exists && currentDir.GetDirectories().Length != 0)
                {
                    nonEmptyDirList.Add(currentDir);
                }
                else if (currentDir.Exists && currentDir.GetFileSystemInfos().Length == 0 && (now - currentDir.CreationTime).TotalDays > 7)
                {
                    // 删除放在后面
                    //文件夹为空, 并且空目录至少3天没有使用
                    try
                    {
                        currentDir.Delete();
                        delCount++;
                        NLogHelper.Trace("删除空目录:" + currentDir.FullName);
                    }
                    catch (Exception ex)
                    {
                        NLogHelper.Warn($"删除空目录{currentDir.FullName}失败:{ex}");
                    }
                }
            }

            //递归子目录
            foreach (var subDir in nonEmptyDirList)
            {
                delCount += CleanEmptyDirectory(subDir.FullName, currentDepth + 1);
            }

            return(delCount);
        }
        /// <summary>
        /// 清理文件及空目录
        /// </summary>
        /// <param name="topDir">清理的顶层目录,该目录不会被删除</param>
        /// <param name="fileSearchPatternArr">
        /// 文件搜索模式 *所有文件 *.*有拓展名的文件
        /// *:表示0个或多个字符
        /// ?:表示0个或1个字符
        /// 采用*.log|*.txt格式,多个项通过|隔开,该功能是通过自己写代码实现的
        /// </param>
        /// <param name="expireTime">文件过期时间</param>
        /// <param name="currentDepth">当前递归深度</param>
        /// <returns>返回删除文件的个数</returns>
        private int CleanFiles(string topDir, string[] fileSearchPatternArr, DateTime expireTime, int currentDepth)
        {
            if (currentDepth > MaxRecursiveDepth)
            {
                //目录的快捷方式会被认为是一个文件
                NLogHelper.Warn("日志文件夹深度太大或者存在快捷方式导致无穷递归");
                return(0);
            }

            DirectoryInfo dirInfo = new DirectoryInfo(topDir);

            if (!dirInfo.Exists)
            {
                NLogHelper.Warn($"未找到{topDir}目录,无法清理");
                return(0);
            }


            //If you choose AllDirectories and the directory structure contains a link that creates a loop, the search operation enters an infinite loop.
            //FileInfo[] fileInfos = dirInfo.GetFiles(fileSearchPattern, SearchOption.AllDirectories);

            HashSet <string> fileInfos = new HashSet <string>();

            foreach (string searchPatternItem in fileSearchPatternArr)
            {
                //仅搜索当前目录,不递归
                dirInfo.GetFiles(searchPatternItem, SearchOption.TopDirectoryOnly).Select(r => r.FullName).ToList().ForEach(r => fileInfos.Add(r.Trim()));
            }

            //删除文件的个数
            int delCount = 0;

            //删除过期文件
            foreach (string fileName in fileInfos)
            {
                try
                {
                    FileInfo fileInfo = new FileInfo(fileName);
                    //文件过期
                    if (fileInfo.Exists && fileInfo.LastWriteTime < expireTime)
                    {
                        fileInfo.Delete();
                        delCount++;
                        NLogHelper.Trace("成功删除文件:" + fileInfo.FullName);
                    }
                }
                catch (Exception ex)
                {
                    NLogHelper.Warn($"删除文件{fileName}失败:{ex}");
                }
            }

            //递归子文件夹
            DirectoryInfo[] subDirs = dirInfo.GetDirectories();//返回当前目录的子目录。如果没有子目录,则此方法返回一个空数组。 此方法不是递归的。
            foreach (var subDir in subDirs)
            {
                delCount += CleanFiles(subDir.FullName, fileSearchPatternArr, expireTime, currentDepth + 1);
            }

            return(delCount);
        }
        /// <summary>
        /// 构造函数  构造完即开启处理线程
        /// </summary>
        /// <param name="singleDataHandler">单个数据处理</param>
        /// <param name="dataListHandler">如果数据较多,列表处理,如果为null,则不启用列表处理</param>
        /// <param name="exceptionHandler">数据处理异常后的处理</param>
        /// <param name="maxNumberDataInQueue">队列中消息的最大数量,超过该数量,之前的消息将被丢弃 最小是100,如果小于100,将会赋值为100</param>
        /// <param name="isNeedOptimize">是否需要多线程优化消息处理,通常不需要,使用优化是非常危险的行为</param>
        /// <param name="maxBatchSize">最大允许的单次处理批次数量</param>
        public BlockingQueueEx(Action <T> singleDataHandler = null, Action <List <T> > dataListHandler = null, Action <Exception> exceptionHandler = null, int maxNumberDataInQueue = 4096, bool isNeedOptimize = false, int maxBatchSize = 29)
        {
            lock (_locker)
            {
                this._isRunning         = true;
                this._singleDataHandler = singleDataHandler;
                this._exceptionHandler  = exceptionHandler;
                this._isNeedOptimize    = isNeedOptimize;
                this._dataListHandler   = dataListHandler;
                //列表处理函数不为null,启用列表处理
                this._enableListHandler = dataListHandler != null;
                this._maxBatchSize      = maxBatchSize > ThresholdCanBeListHandled?maxBatchSize:ThresholdCanBeListHandled;

                //队列中消息的最大数量,超过该数量,之前的消息将被丢弃 最小是100,如果小于100,将会赋值为100
                if (maxNumberDataInQueue < 100)
                {
                    this._maxNumDataInQueue = 100;
                }
                else
                {
                    this._maxNumDataInQueue = maxNumberDataInQueue;
                }
            }


            _thread = new Thread(() =>
            {
                T item = null;
                Action <T> dataHandlerInThread = null;//单条消息处理
                Action <Exception> exceptionHandlerInThread = null;
                Action <List <T> > dataListHandlerInThread  = null;
                bool enableListHandlerInThread = false;
                int maxBatchSizeInThread       = ThresholdCanBeListHandled;
                bool isNeedOptimizeInThread    = false;//是否需要多线程优化处理,一般不需要

                lock (_locker)
                {
                    dataHandlerInThread       = this._singleDataHandler;
                    exceptionHandlerInThread  = this._exceptionHandler;
                    dataListHandlerInThread   = this._dataListHandler;
                    enableListHandlerInThread = this._enableListHandler;
                    maxBatchSizeInThread      = this._maxBatchSize;
                    isNeedOptimizeInThread    = this._isNeedOptimize;
                }


                while (_isRunning)
                {
                    try
                    {
                        #region 数据处理

                        if (enableListHandlerInThread)
                        {
                            //当前队列数据量
                            int currentCount = _blockingQueue.Count;

                            if (currentCount < ThresholdCanBeListHandled)
                            {
                                #region 单个处理  不需要list处理

                                if (_blockingQueue.TryTake(out item, 419))
                                {
                                    if (isNeedOptimizeInThread)
                                    {
                                        //需要优化性能
                                        T tempItem = item;
                                        Task.Factory.StartNew(() =>
                                        {
                                            try
                                            {
                                                dataHandlerInThread?.Invoke(tempItem);
                                            }
                                            catch (Exception ex)
                                            {
                                                exceptionHandlerInThread?.Invoke(ex);
                                            }
                                        });
                                    }
                                    else
                                    {
                                        try
                                        {
                                            dataHandlerInThread?.Invoke(item);
                                        }
                                        catch (Exception ex)
                                        {
                                            exceptionHandlerInThread?.Invoke(ex);
                                        }
                                    }
                                }

                                #endregion
                            }
                            else
                            {
                                #region 数据较多,列表处理

                                //单次处理的数据量
                                int dataListSize = ThresholdCanBeListHandled;

                                if (currentCount > ThresholdCanBeListHandled * 2)
                                {
                                    dataListSize = ThresholdCanBeListHandled * 2;
                                }

                                //最大单次处理的批次
                                if (currentCount > maxBatchSizeInThread)
                                {
                                    dataListSize = maxBatchSizeInThread;
                                }


                                List <T> dataList = new List <T>();
                                for (int i = 0; i < dataListSize; i++)
                                {
                                    if (_blockingQueue.TryTake(out item, 111))
                                    {
                                        //有数据立刻返回
                                        dataList.Add(item);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                if (isNeedOptimizeInThread)
                                {
                                    //需要优化性能
                                    Task.Factory.StartNew(() =>
                                    {
                                        try
                                        {
                                            dataListHandlerInThread?.Invoke(dataList);
                                        }
                                        catch (Exception ex)
                                        {
                                            exceptionHandlerInThread?.Invoke(ex);
                                        }
                                    });
                                }
                                else
                                {
                                    try
                                    {
                                        dataListHandlerInThread?.Invoke(dataList);
                                    }
                                    catch (Exception ex)
                                    {
                                        exceptionHandlerInThread?.Invoke(ex);
                                    }
                                }

                                #endregion
                            }
                        }
                        else
                        {
                            #region 单个处理  不需要list处理

                            if (_blockingQueue.TryTake(out item, 419))
                            {
                                if (isNeedOptimizeInThread)
                                {
                                    //需要优化性能
                                    T tempItem = item;
                                    Task.Factory.StartNew(() =>
                                    {
                                        try
                                        {
                                            dataHandlerInThread?.Invoke(tempItem);
                                        }
                                        catch (Exception ex)
                                        {
                                            exceptionHandlerInThread?.Invoke(ex);
                                        }
                                    });
                                }
                                else
                                {
                                    try
                                    {
                                        dataHandlerInThread?.Invoke(item);
                                    }
                                    catch (Exception ex)
                                    {
                                        exceptionHandlerInThread?.Invoke(ex);
                                    }
                                }
                            }

                            #endregion
                        }

                        #endregion
                    }
                    catch (Exception ex)
                    {
                        exceptionHandlerInThread?.Invoke(ex);
                    }
                }

                NLogHelper.Trace($"Message处理循环退出");
            });

            //后台线程
            _thread.IsBackground = true;
            _thread.Priority     = ThreadPriority.Normal;

            _thread.Start();
        }
        /// <summary>
        /// 从网络获取时间
        /// </summary>
        /// <param name="url"></param>
        /// <param name="exceptionHandler"></param>
        /// <returns></returns>
        public static DateTime?GetNetworkDateTime(string url, Action <Exception> exceptionHandler = null)
        {
            if (string.IsNullOrWhiteSpace(url))
            {
                return(null);
            }


            NLogHelper.Trace(url);

            HttpWebRequest request  = null;
            WebResponse    response = null;

            try
            {
                request             = (HttpWebRequest)WebRequest.Create(url);
                request.Timeout     = 6000;//单位毫秒
                request.Credentials = CredentialCache.DefaultCredentials;
                request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                response            = request.GetResponse();
                var    headers = response.Headers;
                string dateStr = null;
                foreach (var item in headers.AllKeys)
                {
                    if (item == "Date")
                    {
                        //Http响应的Date
                        dateStr = headers[item];
                        break;
                    }
                }

                if (!string.IsNullOrWhiteSpace(dateStr))
                {
                    //Convert将尽量尝试解析
                    return(Convert.ToDateTime(dateStr));
                }

                return(null);
            }
            catch (Exception e)
            {
                exceptionHandler?.Invoke(e);
                return(null);
            }
            finally
            {
                if (request != null)
                {
                    try
                    {
                        request.Abort();
                    }
                    catch
                    {
                    }
                }

                if (response != null)
                {
                    try
                    {
                        response.Close();
                    }
                    catch
                    {
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// MQ回调
        /// </summary>
        /// <param name="state"></param>
        private static void MqTimerCallBack(object state)
        {
            lock (Slocker)
            {
                if (_isRunning)
                {
                    return;
                }
                _isRunning = true;
            }

            try
            {
                if (!LongRunRabbitConsumer.IsAlive())
                {
                    Thread.Sleep(5500);

                    //延迟,使其能够自动恢复
                    if (!LongRunRabbitConsumer.IsAlive())
                    {
                        if (_isFirstTimeToStartMq)
                        {
                            _isFirstTimeToStartMq = false;

                            NLogHelper.Debug("首次尝试启动MQConsumer");
                            LongRunRabbitConsumer.StartConsumer(ex =>
                            {
                                NLogHelper.Error($"开启MQ失败:{ex}");
                            });
                        }
                        else
                        {
                            _restartCount++;
                            if (_restartCount > 10000000)
                            {
                                _restartCount = 10000;
                            }
                            NLogHelper.Warn($"MQ异常,第{_restartCount}次尝试重启 MQConsumer");
                            LongRunRabbitConsumer.StartConsumer(ex =>
                            {
                                NLogHelper.Error($"开启MQ失败:{ex}");
                            });
                        }
                    }
                }
                else
                {
                    NLogHelper.Trace("检测MQ连接正常");
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Error("MQ定时器异常:" + ex);
            }
            finally
            {
                lock (Slocker)
                {
                    _isRunning = false;
                }
            }
        }