100多行代碼實現6秒完成50萬條多線程併發日誌文件寫入,支持日誌文件分隔 日誌工具類代碼: using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; u ...
100多行代碼實現6秒完成50萬條多線程併發日誌文件寫入,支持日誌文件分隔
日誌工具類代碼:
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Utils { /// <summary> /// 寫日誌類 /// </summary> public class LogUtil { #region 欄位 public static object _lock = new object(); public static string path = "D:\\log"; public static int fileSize = 10 * 1024 * 1024; //日誌分隔文件大小 private static ConcurrentQueue<Tuple<string, string>> msgQueue = new ConcurrentQueue<Tuple<string, string>>(); #endregion #region 靜態構造函數 static LogUtil() { Thread thread = new Thread(new ThreadStart(() => { try { int i; List<string> list; Tuple<string, string> tuple; while (true) { i = 0; list = new List<string>(); while (msgQueue.TryDequeue(out tuple) && i++ < 10000) { list.Add(tuple.Item1.PadLeft(8) + tuple.Item2); } if (list.Count > 0) { WriteFile(list, CreateLogPath()); } Thread.Sleep(1); } } catch { } })); thread.IsBackground = true; thread.Start(); } #endregion #region 寫文件 /// <summary> /// 寫文件 /// </summary> public static void WriteFile(List<string> list, string path) { try { if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } if (!File.Exists(path)) { using (FileStream fs = new FileStream(path, FileMode.Create)) { fs.Close(); } } using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(fs)) { list.ForEach(item => { #region 日誌內容 string value = string.Format(@"{0} {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), item); #endregion sw.WriteLine(value); }); sw.Flush(); } fs.Close(); } } catch { } } #endregion #region 生成日誌文件路徑 /// <summary> /// 生成日誌文件路徑 /// </summary> public static string CreateLogPath() { int index = 0; string logPath; bool bl = true; do { index++; logPath = Path.Combine(path, "Log" + DateTime.Now.ToString("yyyyMMdd") + (index == 1 ? "" : "_" + index.ToString()) + ".txt"); if (File.Exists(logPath)) { FileInfo fileInfo = new FileInfo(logPath); if (fileInfo.Length < fileSize) { bl = false; } } else { bl = false; } } while (bl); return logPath; } #endregion #region 寫錯誤日誌 /// <summary> /// 寫錯誤日誌 /// </summary> public static void LogError(string log) { msgQueue.Enqueue(new Tuple<string, string>("[Error] ", log)); } #endregion #region 寫操作日誌 /// <summary> /// 寫操作日誌 /// </summary> public static void Log(string log) { msgQueue.Enqueue(new Tuple<string, string>("[Info] ", log)); } #endregion } }View Code
測試代碼:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Utils; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { LogUtil.path = Application.StartupPath + "\\log"; //初始化日誌路徑 } private void button1_Click(object sender, EventArgs e) { for (int n = 0; n < 10; n++) { Thread thread = new Thread(new ThreadStart(() => { int i = 0; for (int k = 0; k < 50000; k++) { LogUtil.Log((i++).ToString() + " abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcda3.1415bcdabcdabcdabcdabc@#$%^&dabcdabcdabcdabcdabcdabcdabcdabcd"); } })); thread.IsBackground = true; thread.Start(); } } } }View Code
測試截圖: