public class NtLogV4 //可能无法使用 { private Queue<LogContentV4> buffer = new Queue<LogContentV4>(); public string LogPath { get; } private string curfilepath = string.Empty; private string errorLgFile = string.Empty; //定义从Exception到Fault这5个层级为Error private Task task; //不要删除,多线程写日志时会用到 private Stopwatch watcher = new Stopwatch(); private long maxms, minms, lastms; private volatile bool IsWriting = false; public bool Writing { get { return IsWriting; } } /// <summary> /// 平均耗时 /// </summary> public long AverageConsum { get { return (maxms + minms + lastms) / 3; } } public NtLogV4() { this.LogPath = AppDomain.CurrentDomain.BaseDirectory; ////创建日志文件夹 this.LogPath = CreateLogDirectory(); MakeLogFileName(); maxms = minms = lastms = 0; } public void Enqueue(LogContentV4 log) { this.buffer.Enqueue(log); } public void Enqueue(ref List<LogContentV4> logs) { foreach (LogContentV4 log in logs) { this.buffer.Enqueue(log); } } public void Enqueue(Queue<LogContentV4> rlogs) { foreach (LogContentV4 log in rlogs) { this.buffer.Enqueue(log); } } public void Enqueue(ref Queue<LogContentV4> rlogs) { while (rlogs.Count > 0) { this.buffer.Enqueue(rlogs.Dequeue()); } } public void OnLogging(ref Queue<LogContentV4> logs) { for (int i = 0; i < logs.Count; i++) { this.buffer.Enqueue(logs.Dequeue()); } this.UpdatePathFileName(); if (this.IsWriting == false && this.buffer.Count > 0) { WriteLogByThreadV5(); } } private static string CreateLogDirectory() { string path = AppDomain.CurrentDomain.BaseDirectory; // 获取当前应用程序域的名称(通常是程序集名称) string assemblyName = AppDomain.CurrentDomain.FriendlyName; // 去掉路径和扩展名,只保留文件名 assemblyName = Path.GetFileNameWithoutExtension(assemblyName); // 组合成完整的路径 path = System.IO.Path.Combine(path, assemblyName + "Log"); //TempLog.logging(path); //创建日志文件夹 Directory.CreateDirectory(path); return path; } private void UpdatePathFileName() { string path = AppDomain.CurrentDomain.BaseDirectory; // 获取当前应用程序域的名称(通常是程序集名称) string assemblyName = AppDomain.CurrentDomain.FriendlyName; // 去掉路径和扩展名,只保留文件名 assemblyName = Path.GetFileNameWithoutExtension(assemblyName); // 组合成完整的路径 path = System.IO.Path.Combine(path, assemblyName + "Log"); //TempLog.logging(path); //创建日志文件夹 Directory.CreateDirectory(path); string dn = DateTime.Now.ToString("yyyy-MM-dd"); this.curfilepath = Path.Combine(this.LogPath, assemblyName + dn + ".log"); this.errorLgFile = Path.Combine(this.LogPath, assemblyName + dn + "err.log"); } private void MakeLogFileName() { // 获取当前应用程序域的名称(通常是程序集名称) string assemblyName = AppDomain.CurrentDomain.FriendlyName; // 去掉路径和扩展名,只保留文件名 assemblyName = Path.GetFileNameWithoutExtension(assemblyName); string dn = DateTime.Now.ToString("yyyy-MM-dd"); this.curfilepath = Path.Combine(this.LogPath, assemblyName + dn + ".log"); this.errorLgFile = Path.Combine(this.LogPath, assemblyName + dn + "err.log"); } public void WriteLogFile() { using (StreamWriter writer = new StreamWriter(this.curfilepath, true)) // true表示追加模式 { foreach (var cnt in this.buffer) { writer.WriteLine(cnt.ToString()); } } } public void WriteErrorLog() { using (StreamWriter writer = new StreamWriter(this.errorLgFile, true)) // true表示追加模式 { foreach (LogContentV4 cnt in this.buffer) { if (cnt._Level >= LogLevel.Warning) writer.WriteLine(LogContentV4X.TraceDetail(cnt)); } } } //发现它仍然阻塞主线程 //注意只有一个线程写,不能多个线程同时写文件。 //请注意,Buffer.Remove(cnt) 在循环中可能会导致问题,因为从集合中移除元素会改变集合的大小,从而可能导致迭代器失效。为了避免这个问题,可以先收集需要删除的元素,然后在循环结束后统一删除它们。 public void WriteLogByThreadV5() { this.watcher.Start(); this.IsWriting = true; Queue<LogContentV4> errlogs = new Queue<LogContentV4>(); // 使用Task.Run在后台线程中执行文件写入操作 this.task = Task.Run(() => { //FileStream可以设置成独享锁定模式,防止 线程互斥 using (FileStream fs1 = new FileStream(this.curfilepath, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer = new StreamWriter(fs1)) { //foreach (var cnt in queue) //{ // writer.WriteLine(cnt.ToString()); // ; // if (cnt.Level >= LogLevel.Warning) // errlogs.Enqueue(cnt); //} while (this.buffer.Count > 0) { var tmp = this.buffer.Dequeue(); writer.WriteLine(tmp.ToString()); if (tmp._Level >= LogLevel.Warning) errlogs.Enqueue(tmp); } } } //如果没有errlog就不写 if (errlogs.Count > 0) { using (FileStream fs2 = new FileStream(this.errorLgFile, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer2 = new StreamWriter(fs2)) { for (int i = 0; i < errlogs.Count; i++) { writer2.WriteLine(LogContentV4X.TraceDetail(errlogs.Dequeue())); } } } } //Buffer没有上锁是希望它尽快完成操作,但有风险 }); this.watcher.Stop(); this.IsWriting = false; if (this.lastms > 0 && this.lastms > this.maxms) { this.maxms = this.lastms; } if (this.lastms > 0 && this.minms == 0) this.minms = this.lastms; if (this.lastms > 0 && this.lastms < this.minms) { this.minms = this.lastms; } this.lastms = watcher.ElapsedMilliseconds; } public void WriteLogByThreadV8() { this.watcher.Start(); this.IsWriting = true; Queue<LogContentV4> errlogs = new Queue<LogContentV4>(); // 使用Task.Run在后台线程中执行文件写入操作 this.task = Task.Run(() => { //刷新文件路径 MakeLogFileName(); //FileStream可以设置成独享锁定模式,防止 线程互斥 using (FileStream fs1 = new FileStream(this.curfilepath, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer = new StreamWriter(fs1)) { //foreach (var cnt in queue) //{ // writer.WriteLine(cnt.ToString()); // ; // if (cnt.Level >= LogLevel.Warning) // errlogs.Enqueue(cnt); //} while (this.buffer.Count > 0) { var tmp = this.buffer.Dequeue(); writer.WriteLine(tmp.ToString()); if (tmp._Level >= LogLevel.Warning) errlogs.Enqueue(tmp); } } } //如果没有errlog就不写 if (errlogs.Count > 0) { using (FileStream fs2 = new FileStream(this.errorLgFile, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer2 = new StreamWriter(fs2)) { for (int i = 0; i < errlogs.Count; i++) { writer2.WriteLine(LogContentV4X.TraceDetailV2(errlogs.Dequeue())); } } } } //Buffer没有上锁是希望它尽快完成操作,但有风险 }); this.watcher.Stop(); this.IsWriting = false; if (this.lastms > 0 && this.lastms > this.maxms) { this.maxms = this.lastms; } if (this.lastms > 0 && this.minms == 0) this.minms = this.lastms; if (this.lastms > 0 && this.lastms < this.minms) { this.minms = this.lastms; } this.lastms = watcher.ElapsedMilliseconds; } public void WriteLogByThreadV8(Queue<LogContentV4> logqueue) { Enqueue(logqueue); this.watcher.Start(); this.IsWriting = true; Queue<LogContentV4> errlogs = new Queue<LogContentV4>(); // 使用Task.Run在后台线程中执行文件写入操作 this.task = Task.Run(() => { //刷新文件路径 MakeLogFileName(); //FileStream可以设置成独享锁定模式,防止 线程互斥 using (FileStream fs1 = new FileStream(this.curfilepath, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer = new StreamWriter(fs1)) { //foreach (var cnt in queue) //{ // writer.WriteLine(cnt.ToString()); // ; // if (cnt.Level >= LogLevel.Warning) // errlogs.Enqueue(cnt); //} while (this.buffer.Count > 0) { var tmp = this.buffer.Dequeue(); writer.WriteLine(tmp.ToString()); if (tmp._Level >= LogLevel.Warning) errlogs.Enqueue(tmp); } } } //如果没有errlog就不写 if (errlogs.Count > 0) { using (FileStream fs2 = new FileStream(this.errorLgFile, FileMode.Append, FileAccess.Write, FileShare.None)) { using (StreamWriter writer2 = new StreamWriter(fs2)) { for (int i = 0; i < errlogs.Count; i++) { writer2.WriteLine(LogContentV4X.TraceDetailV2(errlogs.Dequeue())); } } } } //Buffer没有上锁是希望它尽快完成操作,但有风险 }); this.watcher.Stop(); this.IsWriting = false; if (this.lastms > 0 && this.lastms > this.maxms) { this.maxms = this.lastms; } if (this.lastms > 0 && this.minms == 0) this.minms = this.lastms; if (this.lastms > 0 && this.lastms < this.minms) { this.minms = this.lastms; } this.lastms = watcher.ElapsedMilliseconds; } }NtLogV4
张小明
前端开发工程师
springboot基于vue的城科高校跳蚤二手商城系统设计与实现_r7e85p1m
目录已开发项目效果实现截图已开发项目效果实现截图开发技术系统开发工具:核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部…
那个曾不可一世的甲骨文,正在被AI时代抛弃
出品I下海fallsea 撰文I胡不知 2025年12月11日上午10点17分,纽约证券交易所的交易员们盯着甲骨文的K线图集体沉默——这条曾被机构视为“防御性资产”的曲线,在开盘不到70分钟内被砸出16.1%的断崖式跌幅,1020亿美元市值蒸发的速度ÿ…
微服务面试题:概览
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…
蓝牙数据包从底层到应用层协议一层套一层
下面给你最简短、最清晰、最准确的蓝牙协议栈按层说明 —— 从硬件 → 内核 → 用户空间 → 应用程序,附带每一层的协议格式 层层封装关系。sudo btmon 命令结果: > ACL Data RX: Handle 3 flags 0x02 dlen 9 #4 [hci0] 37.417566…
EKB 与 OP-TEE 如何真正保护你的密钥
📺 B站视频讲解(Bilibili):https://www.bilibili.com/video/BV1k1C9BYEAB/ 📘 《Yocto项目实战教程》京东购买链接:Yocto项目实战教程 Jetson 安全体系的最后一块拼图:EKB 与 OP-TEE 如何真正保…
arXiv 2025|RGB-Th-Bench:第一个专注于可见光–热成像理解的密集型视觉语言模型基准
一、论文信息 论文标题:RGB-Th-Bench: A Dense Benchmark for Visual-Thermal Understanding of Vision-Language Models 作者:Mehdi Moshtaghi, Siavash H. Khajavi, Joni Pajarinen 机构:Aalto University,KTH Royal Institute …