C# 中的 AutoResetEvent 关键字

在工做的任务中,须要对客户端和服务端 通讯包进行落地。把这个作成通用的模块,在高并发和多线程下,也可以工做。算法

在查阅了大众化日志方案后,决定采用:写日志和写文件分离的方式进行。大概内容图:安全

log.png

须要记录是通讯包,将须要记录的通讯包推送到队列,再由一个专门的线程去读取队列,将出队列的数据写到文件中。这样将每次直接IO瓶颈,转化成存储队列的大小,瓶颈变成了内存的大小。上代码:bash

// 扫描队列,写文件的线程
private static readonly Thread LogThread;

// 自定义线程安全的Queue
private static readonly ConcurrentQueue<Message> LogQueue; 

// 多线程下,操做统一资源的锁
private static readonly object SyncRoot;

// 在队列没有数据时,线程中止扫描标志
private static readonly AutoResetEvent AutoReset = null; 
复制代码
// 构造函数
static Utils()
{
   AutoReset = new AutoResetEvent(false);
   SyncRoot = new object();
   LogThread = new Thread(WriteLog);
   LogQueue = new ConcurrentQueue<Message>();
   LogThread.Start();
}
复制代码
// 记录日志
public static void Log(List<Message> msg)
{
  foreach (var item in msg)
  {
      // 队列入队
      LogQueue.Enqueue(item);
   }
   // 激活扫描中止的线程(发出信号)
   AutoReset.Set();
}
复制代码
// 写入日志
private static void WriteLog()
{
   var list = new List<Message>();
   while (true)
   {
   	  // 若是队列中有数据
      if (LogQueue.Count() > 0)
      {
         IT2ESBMessage _msg;
         // 出队列
         LogQueue.TryDequeue(out _msg);
         if (_msg!=null)
         {
            list.Add(_msg);
         }
      }
      else
      {
          if (list.Count>0)
          {
              // 加锁,在多线程操做的时候,保证安全
              lock (SyncRoot)
              {
                  foreach (var item in list)
                  {
                      ProcessWriteLog(item); 
                   }    
               }
               ist.Clear();
            }
            // 在这里,线程会被暂停,直到收到信号;
            AutoReset.WaitOne();
          }
      }
}
复制代码
// 写文件
private static void ProcessWriteLog(Message msg)
{
   try
   {
      FileStream fs;
      fs = new FileStream(_fileName, FileMode.Append, FileAccess.Write);
      //TODO,进行对文件的写操做,省略一万字     
   }
   catch (Exception ex)
   {
      Debug.WriteLine(string.Format("写入日志失败,缘由:{0}", ex.Message));
   }
}
复制代码

AutoResetEvent 关键字多线程

  • Reset ():将事件状态设置为非终止状态,致使线程阻止;并发

  • Set ():发送信号到等待线程以继续其工做;函数

有点相似于计算机中的信号量,回顾《操做系统》中的信号量吧,什么银行家算法,什么信号量已经忘得一干二净了。高并发

信号量 用在多线程多任务同步的,一个线程完成了某一个动做就经过信号量告诉别的线程,别的线程再进行某些动做。ui

互斥锁 是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就没法访问,直到这个线程unlock,其余的线程才开始能够利用这个资源spa

相关文章
相关标签/搜索