您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)C#開(kāi)發(fā)高性能Log Help類(lèi)設(shè)計(jì)開(kāi)發(fā)的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著小編一起來(lái)看看吧。
概述
項(xiàng)目中要在操作數(shù)據(jù)庫(kù)的異常處理中加入寫(xiě)Log日志,對(duì)于商業(yè)上有要求,寫(xiě)log時(shí)對(duì)其它操作盡可能影響小,不能因?yàn)榧尤雔og導(dǎo)致耗時(shí)太多。
設(shè)計(jì)思想
在寫(xiě)入日志時(shí)利用Queue來(lái)管理,寫(xiě)日志有一個(gè)專(zhuān)門(mén)的backgroud線(xiàn)程來(lái)處理,如果沒(méi)有日志要寫(xiě),這個(gè)線(xiàn)程處于wait狀態(tài),這就有了線(xiàn)程的異步處理。
簡(jiǎn)單的實(shí)現(xiàn)方式
//<summary> //Write Log //<summary> public static void WriteLog(string logFile, string msg) { try { System.IO.StreamWriter sw = System.IO.File.AppendText( logPath + LogFilePrefix +" "+ logFile + " " + DateTime.Now.ToString("yyyyMMdd") + ".Log" ); sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss: ") + msg); sw.Close(); } catch (Exception) { throw; } }
我們的設(shè)計(jì)圖
而后我們?cè)贏ddLogMessage時(shí)semaphore.Release()就能喚醒wait中的log 線(xiàn)程。
代碼設(shè)計(jì)
/// <summary> /// Author: spring yang /// Create time:2012/3/30 /// Log Help class /// </summary> /// <remarks>High performance log class</remarks> public class Log : IDisposable { //Log Message queue private static Queue<LogMessage> _logMessages; //log save directory private static string _logDirectory; //log write file state private static bool _state; //log type private static LogType _logType; //log life time sign private static DateTime _timeSign; //log file stream writer private static StreamWriter _writer; /// <summary> /// Wait enqueue wirte log message semaphore will release /// </summary> private Semaphore _semaphore; /// <summary> /// Single instance /// </summary> private static Log _log; /// <summary> /// Gets a single instance /// </summary> public static Log LogInstance { get { return _log ?? (_log = new Log()); } } private object _lockObjeck; /// <summary> /// Initialize Log instance /// </summary> private void Initialize() { if (_logMessages == null) { _state = true; string logPath = System.Configuration.ConfigurationManager.AppSettings["LogDirectory"]; _logDirectory = string.IsNullOrEmpty(logPath) ? ".\\log\\" : logPath; if (!Directory.Exists(_logDirectory)) Directory.CreateDirectory(_logDirectory); _logType = LogType.Daily; _lockObjeck=new object(); _semaphore = new Semaphore(0, int.MaxValue, Constants.LogSemaphoreName); _logMessages = new Queue<LogMessage>(); var thread = new Thread(Work) {IsBackground = true}; thread.Start(); } } /// <summary> /// Create a log instance /// </summary> private Log() { Initialize(); } /// <summary> /// Log save name type,default is daily /// </summary> public LogType LogType { get { return _logType; } set { _logType = value; } } /// <summary> /// Write Log file work method /// </summary> private void Work() { while (true) { //Determine log queue have record need wirte if (_logMessages.Count > 0) { FileWriteMessage(); } else if (WaitLogMessage()) break; } } /// <summary> /// Write message to log file /// </summary> private void FileWriteMessage() { LogMessage logMessage=null; lock (_lockObjeck) { if(_logMessages.Count>0) logMessage = _logMessages.Dequeue(); } if (logMessage != null) { FileWrite(logMessage); } } /// <summary> /// The thread wait a log message /// </summary> /// <returns>is close or not</returns> private bool WaitLogMessage() { //determine log life time is true or false if (_state) { WaitHandle.WaitAny(new WaitHandle[] { _semaphore }, -1, false); return false; } FileClose(); return true; } /// <summary> /// Gets file name by log type /// </summary> /// <returns>log file name</returns> private string GetFilename() { DateTime now = DateTime.Now; string format = ""; switch (_logType) { case LogType.Daily: _timeSign = new DateTime(now.Year, now.Month, now.Day); _timeSign = _timeSign.AddDays(1); format = "yyyyMMdd'.log'"; break; case LogType.Weekly: _timeSign = new DateTime(now.Year, now.Month, now.Day); _timeSign = _timeSign.AddDays(7); format = "yyyyMMdd'.log'"; break; case LogType.Monthly: _timeSign = new DateTime(now.Year, now.Month, 1); _timeSign = _timeSign.AddMonths(1); format = "yyyyMM'.log'"; break; case LogType.Annually: _timeSign = new DateTime(now.Year, 1, 1); _timeSign = _timeSign.AddYears(1); format = "yyyy'.log'"; break; } return now.ToString(format); } /// <summary> /// Write log file message /// </summary> /// <param name="msg"></param> private void FileWrite(LogMessage msg) { try { if (_writer == null) { FileOpen(); } else { //determine the log file is time sign 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); } } /// <summary> /// Open log file write log message /// </summary> private void FileOpen() { _writer = new StreamWriter(Path.Combine(_logDirectory, GetFilename()), true, Encoding.UTF8); } /// <summary> /// Close log file /// </summary> private void FileClose() { if (_writer != null) { _writer.Flush(); _writer.Close(); _writer.Dispose(); _writer = null; } } /// <summary> /// Enqueue a new log message and release a semaphore /// </summary> /// <param name="msg">Log message</param> public void Write(LogMessage msg) { if (msg != null) { lock (_lockObjeck) { _logMessages.Enqueue(msg); _semaphore.Release(); } } } /// <summary> /// Write message by message content and type /// </summary> /// <param name="text">log message</param> /// <param name="type">message type</param> public void Write(string text, MessageType type) { Write(new LogMessage(text, type)); } /// <summary> /// Write Message by datetime and message content and type /// </summary> /// <param name="dateTime">datetime</param> /// <param name="text">message content</param> /// <param name="type">message type</param> public void Write(DateTime dateTime, string text, MessageType type) { Write(new LogMessage(dateTime, text, type)); } /// <summary> /// Write message ty exception and message type /// </summary> /// <param name="e">exception</param> /// <param name="type">message type</param> public void Write(Exception e, MessageType type) { Write(new LogMessage(e.Message, type)); } #region IDisposable member /// <summary> /// Dispose log /// </summary> public void Dispose() { _state = false; } #endregion } /// <summary> /// Log Type /// </summary> /// <remarks>Create log by daily or weekly or monthly or annually</remarks> public enum LogType { /// <summary> /// Create log by daily /// </summary> Daily, /// <summary> /// Create log by weekly /// </summary> Weekly, /// <summary> /// Create log by monthly /// </summary> Monthly, /// <summary> /// Create log by annually /// </summary> Annually } /// <summary> /// Log Message Class /// </summary> public class LogMessage { /// <summary> /// Create Log message instance /// </summary> public LogMessage() : this("", MessageType.Unknown) { } /// <summary> /// Crete log message by message content and message type /// </summary> /// <param name="text">message content</param> /// <param name="messageType">message type</param> public LogMessage(string text, MessageType messageType) : this(DateTime.Now, text, messageType) { } /// <summary> /// Create log message by datetime and message content and message type /// </summary> /// <param name="dateTime">date time </param> /// <param name="text">message content</param> /// <param name="messageType">message type</param> public LogMessage(DateTime dateTime, string text, MessageType messageType) { Datetime = dateTime; Type = messageType; Text = text; } /// <summary> /// Gets or sets datetime /// </summary> public DateTime Datetime { get; set; } /// <summary> /// Gets or sets message content /// </summary> public string Text { get; set; } /// <summary> /// Gets or sets message type /// </summary> public MessageType Type { get; set; } /// <summary> /// Get Message to string /// </summary> /// <returns></returns> public new string ToString() { return Datetime.ToString(CultureInfo.InvariantCulture) + "\t" + Text + "\n"; } } /// <summary> /// Log Message Type enum /// </summary> public enum MessageType { /// <summary> /// unknown type /// </summary> Unknown, /// <summary> /// information type /// </summary> Information, /// <summary> /// warning type /// </summary> Warning, /// <summary> /// error type /// </summary> Error, /// <summary> /// success type /// </summary> Success }
Test Case:
public static void TestLog() { 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); }
運(yùn)行結(jié)果:
接受Mainz的建議,改了部分代碼。
以上就是C#開(kāi)發(fā)高性能Log Help類(lèi)設(shè)計(jì)開(kāi)發(fā)的示例分析,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。