首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 高效能 Log Helper 設計與實作

     編輯:關於C語言

設計目標

資料庫異常處理需寫入 Log,要求對主流程效能影響極小,採用非同步佇列 + 背景執行緒架構。

核心架構

  • LogMessage:封裝時間、類型、內容。
  • Queue<LogMessage>:生產者-消費者緩衝區。
  • Semaphore:背景執行緒等待訊號,有訊息時喚醒。
  • 單一背景執行緒:循環寫入檔案,支援依日期/週/月/年分檔。
  • Singleton:Log.LogInstance 全域唯一存取點。

Log Helper 架構圖

關鍵程式碼節錄

初始化與背景執行緒


private void Initialize()
{
    if (_logMessages == null)
    {
        _state = true;
        string logPath = ConfigurationManager.AppSettings["LogDirectory"];
        _logDirectory = string.IsNullOrEmpty(logPath) ? ".\\log\\" : logPath;
        if (!Directory.Exists(_logDirectory)) Directory.CreateDirectory(_logDirectory);
        _logType = LogType.Daily;
        _lockObject = new object();
        _semaphore = new Semaphore(0, int.MaxValue, Constants.LogSemaphoreName);
        _logMessages = new Queue();
        var thread = new Thread(Work) { IsBackground = true };
        thread.Start();
    }
}

private void Work()
{
    while (true)
    {
        if (_logMessages.Count > 0) FileWriteMessage();
        else if (WaitLogMessage()) break;
    }
}

寫入檔案與分檔邏輯


private void FileWriteMessage()
{
    LogMessage msg = null;
    lock (_lockObject) { if (_logMessages.Count > 0) msg = _logMessages.Dequeue(); }
    if (msg != null) FileWrite(msg);
}

private void FileWrite(LogMessage msg)
{
    try
    {
        if (_writer == null) FileOpen();
        else if (DateTime.Now >= _timeSign) { FileClose(); FileOpen(); } // 跨周期換檔

        _writer.WriteLine(Constants.LogMessageTime + msg.Datetime);
        _writer.WriteLine(Constants.LogMessageType + msg.Type);
        _writer.WriteLine(Constants.LogMessageContent + msg.Text);
        _writer.Flush();
    }
    catch (Exception e) { Console.Out.Write(e); }
}

公開寫入介面


public void Write(LogMessage msg)
{
    if (msg != null)
    {
        lock (_lockObject) { _logMessages.Enqueue(msg); _semaphore.Release(); }
    }
}
public void Write(string text, MessageType type) => Write(new LogMessage(text, type));
public void Write(DateTime dt, string text, MessageType type) => Write(new LogMessage(dt, text, type));
public void Write(Exception ex, MessageType type) => Write(new LogMessage(ex.Message, type));

測試案例與輸出


Log.LogInstance.Write("Test Message", MessageType.Information);
Log.LogInstance.Write("one", MessageType.Error);
Log.LogInstance.Write("two", MessageType.Success);
Log.LogInstance.Write("three", MessageType.Warning);

Log 輸出範例

優化建議 (參考 Mainz)

  • 使用 ConcurrentQueue 簡化鎖操作。
  • 引入 BlockingCollection 取代 Semaphore + Queue。
  • 支援非同步 WriteAsync 避免呼叫端阻塞。
  • 加入日誌等級過濾、結構化日誌 (JSON) 輸出。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved