資料庫異常處理需寫入 Log,要求對主流程效能影響極小,採用非同步佇列 + 背景執行緒架構。
Log.LogInstance 全域唯一存取點。
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);

ConcurrentQueue 簡化鎖操作。BlockingCollection 取代 Semaphore + Queue。WriteAsync 避免呼叫端阻塞。