ManualResetEvent线程信号Demo

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Concurrent;
  4 using System.Collections.Generic;
  5 using System.IO;
  6 using System.Linq;
  7 using System.Security.Permissions;
  8 using System.Text;
  9 using System.Threading;
 10 
 11 namespace Log测试
 12 {
 13     public class LogHeper
 14     {
 15         /// <summary>
 16         /// 线程安全队列
 17         /// </summary>
 18         private static readonly ConcurrentQueue<string> _que = new ConcurrentQueue<string>();
 19 
 20         /// <summary>
 21         /// 线程信号事件
 22         /// </summary>
 23         private static readonly ManualResetEvent _mre = new ManualResetEvent(false);
 24 
 25         /// <summary>
 26         /// 线程安全哈希表(添加Log类型)
 27         /// </summary>
 28         private static Hashtable LogHast = new Hashtable();
 29 
 30         /// <summary>
 31         /// 线程取消信号
 32         /// </summary>
 33         private static CancellationTokenSource token = null;
 34 
 35         /// <summary>
 36         /// 写日志线程
 37         /// </summary>
 38         private static Thread th;
 39 
 40         /// <summary>
 41         /// 日志类型枚举
 42         /// </summary>
 43         private enum LogType
 44         {
 45             INFO, ERROR
 46         }
 47 
 48         /// <summary>
 49         /// 开始运行写日志线程
 50         /// </summary>
 51         public static void Strar()
 52         {
 53             //初始化线程信号
 54             token = new CancellationTokenSource();
 55             th = new Thread(new ThreadStart(WriteLog))
 56             {
 57                 IsBackground = false
 58             };
 59             th.Start();
 60         }
 61 
 62         /// <summary>
 63         /// 取消线程方法
 64         /// </summary>
 65         private static void KillTheThread()
 66         {
 67             //获得信号,不然会阻塞线程,无法停止线程
 68             _mre.Set();
 69             token.Cancel();
 70             //  th.Abort();
 71         }
 72 
 73         /// <summary>
 74         /// 外部调用取消线程
 75         /// </summary>
 76         public static void Stop()
 77         {
 78             KillTheThread();
 79         }
 80 
 81         /// <summary>
 82         /// 外部调用写入Info信息
 83         /// 加入ConcurrentQueue集合
 84         /// ManualResetEvent设置为有信号模式
 85         /// </summary>
 86         /// <param name="data">传入的信息</param>
 87         public static void WriteInfoLog(string data)
 88         {
 89             if (string.IsNullOrEmpty(data)) return;
 90 
 91             LogHast.Add(LogType.INFO, data);
 92             System.Diagnostics.Debug.WriteLine(data);
 93             _que.Enqueue($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 【INFO】 : {data}
");
 94             _mre.Set();
 95         }
 96 
 97         /// <summary>
 98         /// 外部调用写入Error信息
 99         /// </summary>
100         /// <param name="data"></param>
101         public static void WriteErrorLog(string data)
102         {
103             if (string.IsNullOrEmpty(data)) return;
104 
105             LogHast.Add(LogType.ERROR, data);
106             System.Diagnostics.Debug.WriteLine(data);
107             _que.Enqueue($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 【ERROR】 : {data}
");
108             _mre.Set();
109         }
110 
111         /// <summary>
112         /// 写日志方法
113         /// </summary>
114         private static void WriteLog()
115         {
116             try
117             {
118                 string path = AppDomain.CurrentDomain.BaseDirectory + @"logs";
119                 if (!Directory.Exists(path)) Directory.CreateDirectory(path);
120                 while (!token.IsCancellationRequested)
121                 {
122                     string fileInfoPath = Path.Combine(path, DateTime.Now.ToString("yyyy-MM-dd HH") + " 【INFO】.txt");
123                     string fileErrorPath = Path.Combine(path, DateTime.Now.ToString("yyyy-MM-dd HH") + " 【ERROR】.txt");
124                     _mre.WaitOne();
125                     if (_que.Count > 0 && _que.TryDequeue(out string msg))
126                     {
127                         lock (LogHast.SyncRoot)
128                         {
129                             if (LogHast.ContainsKey(LogType.ERROR))
130                             {
131                                 File.AppendAllText(fileErrorPath, msg);
132                                 LogHast.Remove(LogType.ERROR);
133                             }
134                             else
135                             {
136                                 File.AppendAllText(fileInfoPath, msg);
137                                 LogHast.Remove(LogType.INFO);
138                             }
139                         }
140                     }
141                     _mre.Reset();
142                     Thread.Sleep(1);
143                 }
144                 System.Diagnostics.Debug.WriteLine("退出");
145             }
146             catch (ThreadAbortException ex)
147             {
148                 throw ex;
149             }
150             finally
151             {
152                 _mre.Dispose();
153             }
154         }
155     }
156 }
View Code

本文来自博客园,作者:云辰,转载请注明原文链接:https://www.cnblogs.com/yunchen/p/15036884.html

原文地址:https://www.cnblogs.com/yunchen/p/15036884.html