十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本篇文章给大家分享的是有关C#开发高性能Log Help类设计开发的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册、虚拟空间、营销软件、网站建设、漳平网站维护、网站推广。
概述
项目中要在操作数据库的异常处理中加入写Log日志,对于商业上有要求,写log时对其它操作尽可能影响小,不能因为加入log导致耗时太多。
设计思想
在写入日志时利用Queue来管理,写日志有一个专门的backgroud线程来处理,如果没有日志要写,这个线程处于wait状态,这就有了线程的异步处理。
简单的实现方式
////Write Log // 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; } }
我们的设计图
而后我们在AddLogMessage时semaphore.Release()就能唤醒wait中的log 线程。
代码设计
////// Author: spring yang /// Create time:2012/3/30 /// Log Help class /// ///High performance log class public class Log : IDisposable { //Log Message queue private static Queue_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; /// /// Wait enqueue wirte log message semaphore will release /// private Semaphore _semaphore; ////// Single instance /// private static Log _log; ////// Gets a single instance /// public static Log LogInstance { get { return _log ?? (_log = new Log()); } } private object _lockObjeck; ////// Initialize Log instance /// 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(); var thread = new Thread(Work) {IsBackground = true}; thread.Start(); } } /// /// Create a log instance /// private Log() { Initialize(); } ////// Log save name type,default is daily /// public LogType LogType { get { return _logType; } set { _logType = value; } } ////// Write Log file work method /// private void Work() { while (true) { //Determine log queue have record need wirte if (_logMessages.Count > 0) { FileWriteMessage(); } else if (WaitLogMessage()) break; } } ////// Write message to log file /// private void FileWriteMessage() { LogMessage logMessage=null; lock (_lockObjeck) { if(_logMessages.Count>0) logMessage = _logMessages.Dequeue(); } if (logMessage != null) { FileWrite(logMessage); } } ////// The thread wait a log message /// ///is close or not 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; } ////// Gets file name by log type /// ///log file name 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); } ////// Write log file message /// /// 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); } } ////// Open log file write log message /// private void FileOpen() { _writer = new StreamWriter(Path.Combine(_logDirectory, GetFilename()), true, Encoding.UTF8); } ////// Close log file /// private void FileClose() { if (_writer != null) { _writer.Flush(); _writer.Close(); _writer.Dispose(); _writer = null; } } ////// Enqueue a new log message and release a semaphore /// /// Log message public void Write(LogMessage msg) { if (msg != null) { lock (_lockObjeck) { _logMessages.Enqueue(msg); _semaphore.Release(); } } } ////// Write message by message content and type /// /// log message /// message type public void Write(string text, MessageType type) { Write(new LogMessage(text, type)); } ////// Write Message by datetime and message content and type /// /// datetime /// message content /// message type public void Write(DateTime dateTime, string text, MessageType type) { Write(new LogMessage(dateTime, text, type)); } ////// Write message ty exception and message type /// /// exception /// message type public void Write(Exception e, MessageType type) { Write(new LogMessage(e.Message, type)); } #region IDisposable member ////// Dispose log /// public void Dispose() { _state = false; } #endregion } ////// Log Type /// ///Create log by daily or weekly or monthly or annually public enum LogType { ////// Create log by daily /// Daily, ////// Create log by weekly /// Weekly, ////// Create log by monthly /// Monthly, ////// Create log by annually /// Annually } ////// Log Message Class /// public class LogMessage { ////// Create Log message instance /// public LogMessage() : this("", MessageType.Unknown) { } ////// Crete log message by message content and message type /// /// message content /// message type public LogMessage(string text, MessageType messageType) : this(DateTime.Now, text, messageType) { } ////// Create log message by datetime and message content and message type /// /// date time /// message content /// message type public LogMessage(DateTime dateTime, string text, MessageType messageType) { Datetime = dateTime; Type = messageType; Text = text; } ////// Gets or sets datetime /// public DateTime Datetime { get; set; } ////// Gets or sets message content /// public string Text { get; set; } ////// Gets or sets message type /// public MessageType Type { get; set; } ////// Get Message to string /// ///public new string ToString() { return Datetime.ToString(CultureInfo.InvariantCulture) + "\t" + Text + "\n"; } } /// /// Log Message Type enum /// public enum MessageType { ////// unknown type /// Unknown, ////// information type /// Information, ////// warning type /// Warning, ////// error type /// Error, ////// success type /// 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); }
运行结果:
接受Mainz的建议,改了部分代码。
以上就是C#开发高性能Log Help类设计开发的示例分析,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。