• C# 赖加载+多线程安全实现日志文件


    优点:懒加载模式,IO流不会重复实例化使用,多线程安全。

    日志基类接口

    1. ///
    2. /// 日志基类接口
    3. ///
    4. public interface LogBase:IDisposable
    5. {
    6. ///
    7. /// 记录信息
    8. ///
    9. /// 消息内容
    10. void LogInfo(string message);
    11. ///
    12. /// 记录警告信息
    13. ///
    14. /// 消息内容
    15. void LogWarning(string message);
    16. ///
    17. /// 记录错误信息
    18. ///
    19. /// 消息内容
    20. void LogError(string message);
    21. }

    FileLogger文件日志类实现LogBase接口

    1. public class FileLogger<T> : LogBase where T : class, new()
    2. {
    3. private StreamWriter streamWriter;
    4. private string _filePath;
    5. private bool _disposed;
    6. private string _className;
    7. private static Lazy> lazy;
    8. private Object writerLock = new Object();
    9. private FileLogger(string filePath, string className)
    10. {
    11. if (string.IsNullOrEmpty(filePath))
    12. return;
    13. _filePath = filePath;
    14. _className = className;
    15. string path = Path.GetDirectoryName(filePath);
    16. if (!Directory.Exists(path))
    17. Directory.CreateDirectory(path);
    18. // 不覆盖
    19. streamWriter = new StreamWriter(filePath,true);
    20. }
    21. public static FileLogger GetInstance(string path = null)
    22. {
    23. if (path == null)
    24. path = System.Environment.CurrentDirectory + "\\Log\\"+ DateTime.Now.ToString("yyyyMMdd")+"\\" + DateTime.Now.ToString("yyyyMMddHH") + ".txt";
    25. lazy = new Lazy>(() =>
    26. {
    27. return new FileLogger(path, typeof(T).Name);
    28. });
    29. return lazy.Value;
    30. }
    31. public void Dispose()
    32. {
    33. Dispose(true);
    34. GC.SuppressFinalize(this);
    35. }
    36. protected virtual void Dispose(bool disposing)
    37. {
    38. lock (writerLock)
    39. {
    40. if (!_disposed)
    41. {
    42. if (disposing)
    43. {
    44. // Release managed resources
    45. _filePath = null;
    46. _className = null;
    47. }
    48. // Release unmanaged resources
    49. streamWriter.Close();
    50. streamWriter.Dispose();
    51. _disposed = true;
    52. }
    53. }
    54. }
    55. public void LogInfo(string message)
    56. {
    57. Write("LogInfo", message, _className);
    58. }
    59. public void LogWarning(string message)
    60. {
    61. Write("LogWarning", message, _className);
    62. }
    63. public void LogError(string message)
    64. {
    65. Write("LogError", message, _className);
    66. }
    67. ///
    68. /// 写入消息方法
    69. ///
    70. /// 消息类型
    71. /// 消息内容
    72. /// 类名
    73. private void Write(string mesType, string message, string className)
    74. {
    75. lock (writerLock)
    76. {
    77. StringBuilder stringBuilder = new StringBuilder(mesType);
    78. stringBuilder.Append("\t");
    79. stringBuilder.Append(className);
    80. stringBuilder.Append("\t");
    81. stringBuilder.Append(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
    82. stringBuilder.Append("\t");
    83. stringBuilder.Append(message);
    84. streamWriter.WriteLine(stringBuilder.ToString());
    85. stringBuilder.Clear();
    86. streamWriter.Flush();
    87. }
    88. }
    89. ~FileLogger()
    90. {
    91. Dispose(false);
    92. }
    93. }

    其它类型实现:

    1. ///
    2. /// 事件日志实现类
    3. ///
    4. ///
    5. internal class EventLogger<T> : LogBase where T : class, new()
    6. {
    7. private readonly Object lockObj=new object();
    8. public void Dispose()
    9. {
    10. throw new NotImplementedException();
    11. }
    12. public void LogError(string message)
    13. {
    14. throw new NotImplementedException();
    15. }
    16. public void LogInfo(string message)
    17. {
    18. lock (lockObj)
    19. {
    20. }
    21. }
    22. public void LogWarning(string message)
    23. {
    24. throw new NotImplementedException();
    25. }
    26. }
    1. ///
    2. /// 数据库实现类
    3. ///
    4. ///
    5. internal class DBLogger<T> : LogBase where T : class, new()
    6. {
    7. public void Dispose()
    8. {
    9. throw new NotImplementedException();
    10. }
    11. public void LogError(string message)
    12. {
    13. throw new NotImplementedException();
    14. }
    15. public void LogInfo(string message)
    16. {
    17. throw new NotImplementedException();
    18. }
    19. public void LogWarning(string message)
    20. {
    21. throw new NotImplementedException();
    22. }
    23. }

    数据库与事件日志文件没有具体实现,需要的话自行实现。

    1. ///
    2. /// 日志可以输出到目标地点
    3. ///
    4. public enum LogTarget
    5. {
    6. ///
    7. /// txt文件
    8. ///
    9. FILE,
    10. ///
    11. /// 数据库
    12. ///
    13. DATABASE,
    14. ///
    15. /// 事件日志
    16. ///
    17. EVENTLOG
    18. }

    看日志工厂:

    1. ///
    2. /// 日志工厂
    3. ///
    4. ///
    5. public class LogFactory<T> where T : class, new()
    6. {
    7. ///
    8. /// 工厂方法
    9. /// 如果是非文件日志,不必传参fileName与path
    10. ///
    11. /// 默认文件
    12. /// 默认以时间格式命名
    13. /// 默认当前项目路径
    14. ///
    15. public static LogBase InstanceLog(LogTarget target = LogTarget.FILE, string fileName = null, string path = null)
    16. {
    17. LogBase logBase = null;
    18. switch (target)
    19. {
    20. case LogTarget.FILE:
    21. if (fileName == null)
    22. fileName = DateTime.Now.ToString("yyyyMMddHH") + ".txt";
    23. if (path == null)
    24. path = System.Environment.CurrentDirectory + "\\Log\\"+ DateTime.Now.ToString("yyyyMMdd");
    25. logBase = FileLogger.GetInstance(Path.Combine(path, fileName));
    26. break;
    27. case LogTarget.DATABASE:
    28. logBase = new DBLogger();
    29. break;
    30. case LogTarget.EVENTLOG:
    31. logBase = new EventLogger();
    32. break;
    33. }
    34. return logBase;
    35. }
    36. }

    调用

    1. LogBase log = LogFactory.InstanceLog();
    2. for (int i = 0; i < 10000; i++)
    3. {
    4. log.LogInfo("ddd");
    5. log.LogError("sss");
    6. log.LogWarning("qqq");
    7. }
    8. for (int i = 0; i < 10000; i++)
    9. {
    10. new Task(() =>
    11. {
    12. log.LogInfo("ddd");
    13. log.LogError("sss");
    14. log.LogWarning("qqq");
    15. }).Start();
    16. }
    17. int n = 0;
    18. while (true)
    19. {
    20. if (n >= 1000)
    21. break;
    22. new Task(() =>
    23. {
    24. log.LogInfo("ddd");
    25. log.LogError("sss");
    26. log.LogWarning("qqq");
    27. }).Start();
    28. n++;
    29. }
    30. log.LogInfo($"ddd");
    31. log.Dispose();

     log.Dispose();如果就当前函数使用的话就手动调用释放资源,如果全局使用就不需要调用,能手动的尽量手动(比如窗体关闭closed事件调用),不调用的也没事,等待GC调用,不过GC调用不会及时的。

  • 相关阅读:
    【网络研究院】攻击者扫描 160 万个 WordPress 网站以查找易受攻击的插件
    Jenkins pipeline stash实现文件跨节点共享
    小红书种草推广步骤是怎样的,小红书种草效果好吗?
    深度学习数据集—文本、数字、文字识别大合集
    Python如何17行代码画一个爱心
    如何批量删除 Word 文档的只读密码?
    Stage #14 XSS注入:利用CSS内联注释突破防御
    jwt入门
    功能强大的专业网页设计工具:RapidWeaver 8 mac版
    基于SSH开发农产品网上销售系统(购物商城 前台+后台)
  • 原文地址:https://blog.csdn.net/ftfmatlab/article/details/127673726