UdpServer

Udp服务端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
using Notify.Log;namespace UdpSer
{public class UdpServer{// 创建UDP端点,并绑定到本地端口IPEndPoint localEndPoint;// 创建UDP套接字private UdpClient udpServer = new UdpClient();private volatile bool runing = false;private byte[] receiveBytes = new byte[2048];private byte[] sendBytes = new byte[2048];private Queue<LogContentV2> logBuffer = new Queue<LogContentV2>();private Thread listenThread;public int LogBufferCount { get { return this.logBuffer.Count; } }public LogContentV2 Log { get { return this.logBuffer.Dequeue(); } }public UdpServer(){// 创建UDP端点,并绑定到本地端口localEndPoint = new IPEndPoint(IPAddress.Any, 8421);// 创建UDP套接字udpServer = new UdpClient(localEndPoint);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, "UdpServer default constructed."));}public UdpServer(int port = 8421){// 创建UDP端点,并绑定到本地端口localEndPoint = new IPEndPoint(IPAddress.Any, port);// 创建UDP套接字udpServer = new UdpClient(localEndPoint);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, "UdpServer constructed."));}public void Startup(){this.localEndPoint = new IPEndPoint(IPAddress.Any, 8421);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}switch (listenThread.ThreadState){case System.Threading.ThreadState.Unstarted:this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.StopRequested:case System.Threading.ThreadState.AbortRequested:case System.Threading.ThreadState.Aborted:case System.Threading.ThreadState.Stopped:case System.Threading.ThreadState.Suspended:case System.Threading.ThreadState.SuspendRequested:this.listenThread.Abort();this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.Running:runing = true;break;}}public void Startup(int port){this.localEndPoint = new IPEndPoint(IPAddress.Any, port);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}switch (listenThread.ThreadState){case System.Threading.ThreadState.Unstarted:this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.StopRequested:case System.Threading.ThreadState.AbortRequested:case System.Threading.ThreadState.Aborted:case System.Threading.ThreadState.Stopped:case System.Threading.ThreadState.Suspended:case System.Threading.ThreadState.SuspendRequested:this.listenThread.Abort();this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.Running:runing = true;break;}}public void Startup(string ipaddr, int port){this.localEndPoint = new IPEndPoint(IPAddress.Parse(ipaddr), port);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}switch (listenThread.ThreadState){case System.Threading.ThreadState.Unstarted:this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.StopRequested:case System.Threading.ThreadState.AbortRequested:case System.Threading.ThreadState.Aborted:case System.Threading.ThreadState.Stopped:case System.Threading.ThreadState.Suspended:case System.Threading.ThreadState.SuspendRequested:this.listenThread.Abort();this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.Running:runing = true;break;}}public void Stop(){try{this.runing = false;switch (listenThread.ThreadState){case System.Threading.ThreadState.Unstarted:case System.Threading.ThreadState.Aborted:case System.Threading.ThreadState.Stopped:break;case System.Threading.ThreadState.StopRequested:case System.Threading.ThreadState.AbortRequested:Thread.Sleep(2000); // 让线程工作一段时间break;case System.Threading.ThreadState.Suspended:case System.Threading.ThreadState.SuspendRequested:this.listenThread.Abort();break;case System.Threading.ThreadState.Background:case System.Threading.ThreadState.Running:this.listenThread.Join();break;}logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, "UdpServer Stop Called."));}catch (Exception e){logBuffer.Enqueue(new LogContentV2(LogLevelV2.Error, "UdpServer Stop Exception.", e));}System.GC.Collect();logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, "UdpServer Stoped Called System.GC.Collect."));}private void TaskRunning(){Task.Run(() =>{try{while (runing){// 接收数据this.receiveBytes = udpServer.Receive(ref localEndPoint);logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, $"Received {receiveBytes.Length} Bytes."));//处理数据HandleReceiveResposoneModel();// 响应数据if (sendBytes.Length > 0){udpServer.Send(sendBytes, sendBytes.Length, localEndPoint);logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, $"Sented {receiveBytes.Length} Bytes."));}}}catch (Exception e){Console.WriteLine(e.ToString());logBuffer.Enqueue(new LogContentV2(LogLevelV2.Error, "Task.Run Receive Exception.", e));}});}private void HandleReceiveResposoneModel(){logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, $"HandleReceiveResposoneModel"));//this.receiveBytes;//this.sendBytes;string sendMessage = "Message received";sendBytes = Encoding.UTF8.GetBytes(sendMessage);}}internal class Program{static void Main(string[] args){UdpServer udpServer = new UdpServer();udpServer.Startup("127.0.0.1",8421);Console.WriteLine("Press any key to stop the server");Console.ReadKey();udpServer.Stop();}}
}
namespace Notify.Log
{public enum LogLevel{Trace = 0,Debug = 1,Information = 2,Statistic = 3,Warning = 4,Mistake = 6,    //轻微错误Exception = 5,Error = 7,      //逻辑错误Critical = 8,    //严重错误Fault = 9       //致命错误}public enum LogLevelV2{Infor = 2,Excep = 5,Error = 7,}//临时日志是写文本文件,这种操作在高并发程序里会造成程序崩溃public class TempLog{//注意只有一个线程写,不能多个线程同时写文件。static public void logging(List<NtLog> logbuf, string filepath = "./NotifyLog.log"){// 确保日志文件的目录存在  Directory.CreateDirectory(Path.GetDirectoryName(filepath));// 使用StreamWriter写入日志  using (StreamWriter writer = new StreamWriter(filepath, true)) // true表示追加模式  {//writer.WriteLine($"Log Entry: {DateTime.Now} - This is a test log entry.");// 这里可以添加更多的日志写入操作//foreach (NtLog log in logbuf)//{//    writer.WriteLine(log.ToString());//    移除已经写了的缓存//    logbuf.Remove(log);//迭代器安全问题//}for (int i = 0; i < logbuf.Count; i++){//#if DEBUG//                    Console.WriteLine(logbuf[i].ToString());//#endifwriter.WriteLine(logbuf[i].ToString());logbuf.RemoveAt(i);}}}static public void logging(List<NtLog> logbuf){string fileName = $"{DateTime.Now:yyyy-MM-dd}.log"; // 构建文件名,例如 "2023-04-01.log"  string fullPath = Path.Combine("./logs", fileName);// 确保日志文件的目录存在  Directory.CreateDirectory(Path.GetDirectoryName(fullPath));// 使用StreamWriter写入日志  using (StreamWriter writer = new StreamWriter(fullPath, true)) // true表示追加模式  {//writer.WriteLine($"Log Entry: {DateTime.Now} - This is a test log entry.");// 这里可以添加更多的日志写入操作//foreach (NtLog log in logbuf)//{//    writer.WriteLine(log.ToString());//    移除已经写了的缓存//    logbuf.Remove(log);//迭代器安全问题//}for (int i = 0; i < logbuf.Count; i++){
#if DEBUGConsole.WriteLine(logbuf[i].ToString());
#endifwriter.WriteLine(logbuf[i].ToString());logbuf.RemoveAt(i);}}}static public void logging(string message, string logpath){using (StreamWriter writer = new StreamWriter(logpath, true)) // true表示追加模式  {//string fileName = $"{DateTime.Now:yyyy-MM-dd}.log"; // 构建文件名,例如 "2023-04-01.log"  string content = $"{DateTime.Now:yyyy-MM-ddTHH:mm:ss} {message}";writer.WriteLine(content);}}static public void logging(string message){string path = AppDomain.CurrentDomain.BaseDirectory;using (StreamWriter writer = new StreamWriter(path + "//TempLog.log", true)) // true表示追加模式  {//string fileName = $"{DateTime.Now:yyyy-MM-dd}.log"; // 构建文件名,例如 "2023-04-01.log"  string content = $"{DateTime.Now:yyyy-MM-ddTHH:mm:ss} {message}";writer.WriteLine(content);}}}public class LogContentV2{public DateTime Occurrence { get; set; }public LogLevelV2 LevelV2 { get; set; }public StackTrace Trace { get; set; }public string Message { get; set; }public LogContentV2() { }public LogContentV2(LogLevelV2 level, string message){this.Occurrence = DateTime.Now;this.LevelV2 = level;this.Trace = new StackTrace(true);//捕捉当前堆栈this.Message = message;}public LogContentV2(LogLevelV2 level, string message, Exception e){this.Occurrence = DateTime.Now;this.LevelV2 = level;this.Trace = new StackTrace(e, true);//捕捉当前异常堆栈堆栈this.Message = message;}public override string ToString(){return $"{Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.ffff")} {LevelV2.ToString()}:{Message}";//因为ffff会确保输出始终是4位数字,不足的部分用零填充。}}public class LogContent{public DateTime Occurrence { get; set; }public LogLevel Level { get; set; }public StackTrace Trace { get; set; }public string Message { get; set; }public LogContent() { }public LogContent(LogLevel level, string message){this.Occurrence = DateTime.Now;this.Level = level;this.Trace = new StackTrace(true);//捕捉当前堆栈this.Message = message;}public LogContent(LogLevel level, string message, Exception e){this.Occurrence = DateTime.Now;this.Level = level;this.Trace = new StackTrace(e, true);//捕捉当前异常堆栈堆栈this.Message = message;}public override string ToString(){//string tmp = Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF") + " " + Level.ToString() + " " + Message + "\n";//string tmp = $"{Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF")} {Level.ToString()} {Message}";//return tmp;return $"{Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF")} {Level.ToString()}:{Message}";}}public class LogContentX{public DateTime Occurrence { get; set; }public LogLevel Level { get; set; }public StackTrace Trace { get; set; }public string Message { get; set; }public LogContentX() { }public LogContentX(LogLevel level, string message) { this.SetLog(level, message); }public LogContentX(LogLevel level, string message, Exception e) { this.SetLog(level, message, e); }public void SetLog(LogLevel level, string message){this.Occurrence = DateTime.Now;this.Level = level;this.Trace = new StackTrace(true);//捕捉当前堆栈this.Message = message;}public void SetLog(LogLevel level, string message, Exception e){this.Occurrence = DateTime.Now;this.Level = level;this.Trace = new StackTrace(e, true);//捕捉当前异常堆栈堆栈this.Message = message;}public override string ToString(){string tmp = Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF") + " " + Level.ToString() + " " + Message + "\n";return tmp;}public string TraceDetail(){string tmp = Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF") + " " + Level.ToString() + " " + Message + "\n";tmp += this.Trace.ToString() + "\r\n";//StackFrame sf = Trace.GetFrame(0); //tmp += $" Method: {sf.GetMethod()}\r\n";//$" File: {sf.GetFileName()}\r\n" +//$" Line Number: {sf.GetFileLineNumber()}\r\n";return tmp;}public static string TraceDetail(LogContent log){string tmp = log.Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF") + " " + " " + log.Level.ToString() + ":" + log.Message + "\n";tmp += log.Trace.ToString() + "\r\n";//StackFrame sf = Trace.GetFrame(0); //tmp += $" Method: {sf.GetMethod()}\r\n";//$" File: {sf.GetFileName()}\r\n" +//$" Line Number: {sf.GetFileLineNumber()}\r\n";return tmp;}public string TraceTopFrame(){return this.Trace.GetFrame(0).ToString();}public StackFrame TraceTopStackFrame(){return Trace.GetFrame(0);}public StackFrame TraceBottomStackFrame(){return Trace.GetFrame(this.Trace.FrameCount - 1);}public int GetSize(){//在safe环境中无法使用sizeof(DateTime),sizeof(DateTime)用8字节代替// Each character in a string is 2 bytes (UTF-16 encoding).int total = sizeof(LogLevel) + this.Message.Length * 2 + 8;for (int i = 0; i < this.Trace.FrameCount; i++){StackFrame sf = this.Trace.GetFrame(i);//sf.GetFileLineNumber();sf.GetFileName(); sf.GetMethod().Name; total += sf.ToString().Length * 2;}return total;}public static int GetSize(LogContent log){//在safe环境中无法使用sizeof(DateTime),sizeof(DateTime)用8字节代替// Each character in a string is 2 bytes (UTF-16 encoding).int total = sizeof(LogLevel) + log.Message.Length * 2 + 8;for (int i = 0; i < log.Trace.FrameCount; i++){StackFrame sf = log.Trace.GetFrame(i);//sf.GetFileLineNumber();sf.GetFileName(); sf.GetMethod().Name; total += sf.ToString().Length * 2;}return total;}}public class LogBuffer{protected List<LogContent> buf = new List<LogContent>();public List<LogContent> Buffer { get { return buf; } }public LogBuffer(){buf = new List<LogContent>();}public LogBuffer(List<LogContent> buf){this.buf = buf;}public void Insert(LogContent log){this.buf.Add(log);}public void Insert(LogBuffer log){foreach (var item in log.Buffer){this.buf.Add(item);}}public int LogSize(){int size = 0;foreach (LogContent cnt in this.buf){size += LogContentX.GetSize(cnt);}return size;}}public class LogBufQuery{public List<LogContent> Buffer { get; set; }public void TimeOrderAsc(){Buffer.Sort((x, y) => x.Occurrence.CompareTo(y.Occurrence));}public void TimeOrderDsc(){Buffer.Sort((x, y) => y.Occurrence.CompareTo(x.Occurrence));}public List<LogContent> FilterByLoglevel(LogLevel loglevel){return Buffer.FindAll(log => log.Level == loglevel);}}public struct logstatics{public string item;public string value;public long Timestamp;// 将 UNIX 时间戳转换为 DateTime//DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(Timestamp).DateTime;public DateTime FromUnixTime(){return DateTimeOffset.FromUnixTimeSeconds(Timestamp).DateTime;}}public class TotalAccessSattistic{private ulong totalAccess;/// <summary>/// 总访问量/// </summary>public ulong TotalAccess{get{return this.totalAccess;}}private void Reset(){ this.totalAccess = 0; }public void StasticAccess(List<LogContent> buf, string flagstr = "HandleClientComm"){foreach (var cnt in buf){if (cnt.Message == flagstr)this.totalAccess++;}}}//将日志写成文本文件,注意在多线程环境下要排除线程互斥。public class NtLog{//private Queue<LogBuffer> Buff = new Queue<LogBuffer>();private Queue<LogContent> buffer = new Queue<LogContent>();public string LogPath { get; }private string curfilepath = string.Empty;private string errorLgFile = string.Empty;  //定义从Exception到Fault这5个层级为Errorprivate 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 NtLog(){this.LogPath = AppDomain.CurrentDomain.BaseDirectory;创建日志文件夹this.LogPath = CreateLogDirectory();MakeLogFileName();maxms = minms = lastms = 0;}public void Enqueue(LogContent log){this.buffer.Enqueue(log);}public void Enqueue(List<LogContent> logs){foreach (LogContent log in logs){this.buffer.Enqueue(log);}}public void Enqueue(LogBuffer logbuf){foreach (LogContent log in logbuf.Buffer){this.buffer.Enqueue(log);}}public void OnLogging(List<LogContent> logs){//#if DEBUG//            TempLog.logging($"查看原始数据。{logs.Count} ");//{logs.First().Message}//#endif//this.Buff.Enqueue(new LogBuffer(logs));this.Enqueue(logs);this.UpdatePathFileName();if (this.IsWriting == false && this.buffer.Count > 0){//LogBuffer Temp = this.Buff.Dequeue();//while (this.Buff.Count > 0)//{//    Temp.Insert(this.Buff.Dequeue());//}WriteLogByThreadV4(this.buffer);}}public void OnLogging(Queue<LogContent> logs){for (int i = 0; i < logs.Count; i++){this.buffer.Enqueue(logs.Dequeue());}this.UpdatePathFileName();if (this.IsWriting == false && this.buffer.Count > 0){//LogBuffer Temp = this.Buff.Dequeue();//while (this.Buff.Count > 0)//{//    Temp.Insert(this.Buff.Dequeue());//}WriteLogByThreadV4(this.buffer);}}public 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;}public 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");}public 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 (var cnt in this.buffer){if (cnt.Level >= LogLevel.Warning)writer.WriteLine(LogContentX.TraceDetail(cnt));}}}//发现它仍然阻塞主线程//注意只有一个线程写,不能多个线程同时写文件。//请注意,Buffer.Remove(cnt) 在循环中可能会导致问题,因为从集合中移除元素会改变集合的大小,从而可能导致迭代器失效。为了避免这个问题,可以先收集需要删除的元素,然后在循环结束后统一删除它们。public void WriteLogByThread(LogBuffer logs){this.watcher.Start();this.IsWriting = true;//#if DEBUG//            TempLog.logging($"BeofreWriteLog。{this.curfilepath} {this.errorLgFile}");//#endif//this.WriteLogFile// 使用Task.Run在后台线程中执行文件写入操作this.task = Task.Run(() =>{//FileStream可以设置成独享锁定模式,防止 线程互斥using (FileStream fs1 = new FileStream(this.curfilepath, FileMode.Append, FileAccess.Write, FileShare.None),fs2 = new FileStream(this.errorLgFile, FileMode.Append, FileAccess.Write, FileShare.None)){using (StreamWriter writer = new StreamWriter(fs1), writer2 = new StreamWriter(fs2)){foreach (var cnt in logs.Buffer){writer.WriteLine(cnt.ToString());if (cnt.Level >= LogLevel.Warning)writer2.WriteLine(LogContentX.TraceDetail(cnt));}}}//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;}//如果没有errlog就不写public void WriteLogByThreadV2(LogBuffer logs){this.watcher.Start();this.IsWriting = true;Queue<LogContent> errlogs = new Queue<LogContent>();//#if DEBUG//            TempLog.logging($"BeofreWriteLog。{this.curfilepath} {this.errorLgFile}");//#endif//this.WriteLogFile// 使用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 logs.Buffer){writer.WriteLine(cnt.ToString());if (cnt.Level >= LogLevel.Warning)errlogs.Enqueue(cnt);}}}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(errlogs.Dequeue().ToString());}}}}//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 WriteLogByThreadV3(Queue<LogContent> queue){this.watcher.Start();this.IsWriting = true;Queue<LogContent> errlogs = new Queue<LogContent>();//#if DEBUG//            TempLog.logging($"BeofreWriteLog。{this.curfilepath} {this.errorLgFile}");//#endif//this.WriteLogFile// 使用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 (queue.Count > 0){var tmp = queue.Dequeue();writer.WriteLine(tmp.ToString());if (tmp.Level >= LogLevel.Warning)errlogs.Enqueue(tmp);}}}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(errlogs.Dequeue().ToString());}}}}//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 WriteLogByThreadV4(Queue<LogContent> queue){this.watcher.Start();this.IsWriting = true;Queue<LogContent> errlogs = new Queue<LogContent>();//#if DEBUG//            TempLog.logging($"BeofreWriteLog。{this.curfilepath} {this.errorLgFile}");//#endif//this.WriteLogFile// 使用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 (queue.Count > 0){var tmp = queue.Dequeue();writer.WriteLine(tmp.ToString());if (tmp.Level >= LogLevel.Warning)errlogs.Enqueue(tmp);}}}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(LogContentX.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;}}
}

Udp客户端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
using Notify.Log;namespace UdpSer
{public class UdpServer{// 创建UDP端点,并绑定到本地端口IPEndPoint localEndPoint;// 创建UDP套接字private UdpClient udpServer = new UdpClient();private volatile bool runing = false;private byte[] receiveBytes = new byte[2048];private byte[] sendBytes = new byte[2048];private Queue<LogContentV2> logBuffer = new Queue<LogContentV2>();private Thread listenThread;public int LogBufferCount { get { return this.logBuffer.Count; } }public LogContentV2 Log { get { return this.logBuffer.Dequeue(); } }public UdpServer(){// 创建UDP端点,并绑定到本地端口localEndPoint = new IPEndPoint(IPAddress.Any, 8421);// 创建UDP套接字udpServer = new UdpClient(localEndPoint);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, "UdpServer default constructed."));}public UdpServer(int port = 8421){// 创建UDP端点,并绑定到本地端口localEndPoint = new IPEndPoint(IPAddress.Any, port);// 创建UDP套接字udpServer = new UdpClient(localEndPoint);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, "UdpServer constructed."));}public void Startup(){this.localEndPoint = new IPEndPoint(IPAddress.Any, 8421);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}switch (listenThread.ThreadState){case System.Threading.ThreadState.Unstarted:this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.StopRequested:case System.Threading.ThreadState.AbortRequested:case System.Threading.ThreadState.Aborted:case System.Threading.ThreadState.Stopped:case System.Threading.ThreadState.Suspended:case System.Threading.ThreadState.SuspendRequested:this.listenThread.Abort();this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.Running:runing = true;break;}}public void Startup(int port){this.localEndPoint = new IPEndPoint(IPAddress.Any, port);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}switch (listenThread.ThreadState){case System.Threading.ThreadState.Unstarted:this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.StopRequested:case System.Threading.ThreadState.AbortRequested:case System.Threading.ThreadState.Aborted:case System.Threading.ThreadState.Stopped:case System.Threading.ThreadState.Suspended:case System.Threading.ThreadState.SuspendRequested:this.listenThread.Abort();this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.Running:runing = true;break;}}public void Startup(string ipaddr, int port){this.localEndPoint = new IPEndPoint(IPAddress.Parse(ipaddr), port);if (this.listenThread == null || this.listenThread.IsAlive == false){this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程}switch (listenThread.ThreadState){case System.Threading.ThreadState.Unstarted:this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.StopRequested:case System.Threading.ThreadState.AbortRequested:case System.Threading.ThreadState.Aborted:case System.Threading.ThreadState.Stopped:case System.Threading.ThreadState.Suspended:case System.Threading.ThreadState.SuspendRequested:this.listenThread.Abort();this.listenThread = new Thread(new ThreadStart(TaskRunning));this.listenThread.IsBackground = false;//前台线程不会自动退出,thread类默认前台线程,前台线程会阻塞主线程this.listenThread.Start();runing = true;break;case System.Threading.ThreadState.Running:runing = true;break;}}public void Stop(){try{this.runing = false;switch (listenThread.ThreadState){case System.Threading.ThreadState.Unstarted:case System.Threading.ThreadState.Aborted:case System.Threading.ThreadState.Stopped:break;case System.Threading.ThreadState.StopRequested:case System.Threading.ThreadState.AbortRequested:Thread.Sleep(2000); // 让线程工作一段时间break;case System.Threading.ThreadState.Suspended:case System.Threading.ThreadState.SuspendRequested:this.listenThread.Abort();break;case System.Threading.ThreadState.Background:case System.Threading.ThreadState.Running:this.listenThread.Join();break;}logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, "UdpServer Stop Called."));}catch (Exception e){logBuffer.Enqueue(new LogContentV2(LogLevelV2.Error, "UdpServer Stop Exception.", e));}System.GC.Collect();logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, "UdpServer Stoped Called System.GC.Collect."));}private void TaskRunning(){Task.Run(() =>{try{while (runing){// 接收数据this.receiveBytes = udpServer.Receive(ref localEndPoint);logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, $"Received {receiveBytes.Length} Bytes."));//处理数据HandleReceiveResposoneModel();// 响应数据if (sendBytes.Length > 0){udpServer.Send(sendBytes, sendBytes.Length, localEndPoint);logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, $"Sented {receiveBytes.Length} Bytes."));}}}catch (Exception e){Console.WriteLine(e.ToString());logBuffer.Enqueue(new LogContentV2(LogLevelV2.Error, "Task.Run Receive Exception.", e));}});}private void HandleReceiveResposoneModel(){logBuffer.Enqueue(new LogContentV2(LogLevelV2.Infor, $"HandleReceiveResposoneModel"));//this.receiveBytes;//this.sendBytes;string sendMessage = "Message received";sendBytes = Encoding.UTF8.GetBytes(sendMessage);}}internal class Program{static void Main(string[] args){UdpServer udpServer = new UdpServer();udpServer.Startup("127.0.0.1",8421);Console.WriteLine("Press any key to stop the server");Console.ReadKey();udpServer.Stop();}}
}
namespace Notify.Log
{public enum LogLevel{Trace = 0,Debug = 1,Information = 2,Statistic = 3,Warning = 4,Mistake = 6,    //轻微错误Exception = 5,Error = 7,      //逻辑错误Critical = 8,    //严重错误Fault = 9       //致命错误}public enum LogLevelV2{Infor = 2,Excep = 5,Error = 7,}//临时日志是写文本文件,这种操作在高并发程序里会造成程序崩溃public class TempLog{//注意只有一个线程写,不能多个线程同时写文件。static public void logging(List<NtLog> logbuf, string filepath = "./NotifyLog.log"){// 确保日志文件的目录存在  Directory.CreateDirectory(Path.GetDirectoryName(filepath));// 使用StreamWriter写入日志  using (StreamWriter writer = new StreamWriter(filepath, true)) // true表示追加模式  {//writer.WriteLine($"Log Entry: {DateTime.Now} - This is a test log entry.");// 这里可以添加更多的日志写入操作//foreach (NtLog log in logbuf)//{//    writer.WriteLine(log.ToString());//    移除已经写了的缓存//    logbuf.Remove(log);//迭代器安全问题//}for (int i = 0; i < logbuf.Count; i++){//#if DEBUG//                    Console.WriteLine(logbuf[i].ToString());//#endifwriter.WriteLine(logbuf[i].ToString());logbuf.RemoveAt(i);}}}static public void logging(List<NtLog> logbuf){string fileName = $"{DateTime.Now:yyyy-MM-dd}.log"; // 构建文件名,例如 "2023-04-01.log"  string fullPath = Path.Combine("./logs", fileName);// 确保日志文件的目录存在  Directory.CreateDirectory(Path.GetDirectoryName(fullPath));// 使用StreamWriter写入日志  using (StreamWriter writer = new StreamWriter(fullPath, true)) // true表示追加模式  {//writer.WriteLine($"Log Entry: {DateTime.Now} - This is a test log entry.");// 这里可以添加更多的日志写入操作//foreach (NtLog log in logbuf)//{//    writer.WriteLine(log.ToString());//    移除已经写了的缓存//    logbuf.Remove(log);//迭代器安全问题//}for (int i = 0; i < logbuf.Count; i++){
#if DEBUGConsole.WriteLine(logbuf[i].ToString());
#endifwriter.WriteLine(logbuf[i].ToString());logbuf.RemoveAt(i);}}}static public void logging(string message, string logpath){using (StreamWriter writer = new StreamWriter(logpath, true)) // true表示追加模式  {//string fileName = $"{DateTime.Now:yyyy-MM-dd}.log"; // 构建文件名,例如 "2023-04-01.log"  string content = $"{DateTime.Now:yyyy-MM-ddTHH:mm:ss} {message}";writer.WriteLine(content);}}static public void logging(string message){string path = AppDomain.CurrentDomain.BaseDirectory;using (StreamWriter writer = new StreamWriter(path + "//TempLog.log", true)) // true表示追加模式  {//string fileName = $"{DateTime.Now:yyyy-MM-dd}.log"; // 构建文件名,例如 "2023-04-01.log"  string content = $"{DateTime.Now:yyyy-MM-ddTHH:mm:ss} {message}";writer.WriteLine(content);}}}public class LogContentV2{public DateTime Occurrence { get; set; }public LogLevelV2 LevelV2 { get; set; }public StackTrace Trace { get; set; }public string Message { get; set; }public LogContentV2() { }public LogContentV2(LogLevelV2 level, string message){this.Occurrence = DateTime.Now;this.LevelV2 = level;this.Trace = new StackTrace(true);//捕捉当前堆栈this.Message = message;}public LogContentV2(LogLevelV2 level, string message, Exception e){this.Occurrence = DateTime.Now;this.LevelV2 = level;this.Trace = new StackTrace(e, true);//捕捉当前异常堆栈堆栈this.Message = message;}public override string ToString(){return $"{Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.ffff")} {LevelV2.ToString()}:{Message}";//因为ffff会确保输出始终是4位数字,不足的部分用零填充。}}public class LogContent{public DateTime Occurrence { get; set; }public LogLevel Level { get; set; }public StackTrace Trace { get; set; }public string Message { get; set; }public LogContent() { }public LogContent(LogLevel level, string message){this.Occurrence = DateTime.Now;this.Level = level;this.Trace = new StackTrace(true);//捕捉当前堆栈this.Message = message;}public LogContent(LogLevel level, string message, Exception e){this.Occurrence = DateTime.Now;this.Level = level;this.Trace = new StackTrace(e, true);//捕捉当前异常堆栈堆栈this.Message = message;}public override string ToString(){//string tmp = Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF") + " " + Level.ToString() + " " + Message + "\n";//string tmp = $"{Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF")} {Level.ToString()} {Message}";//return tmp;return $"{Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF")} {Level.ToString()}:{Message}";}}public class LogContentX{public DateTime Occurrence { get; set; }public LogLevel Level { get; set; }public StackTrace Trace { get; set; }public string Message { get; set; }public LogContentX() { }public LogContentX(LogLevel level, string message) { this.SetLog(level, message); }public LogContentX(LogLevel level, string message, Exception e) { this.SetLog(level, message, e); }public void SetLog(LogLevel level, string message){this.Occurrence = DateTime.Now;this.Level = level;this.Trace = new StackTrace(true);//捕捉当前堆栈this.Message = message;}public void SetLog(LogLevel level, string message, Exception e){this.Occurrence = DateTime.Now;this.Level = level;this.Trace = new StackTrace(e, true);//捕捉当前异常堆栈堆栈this.Message = message;}public override string ToString(){string tmp = Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF") + " " + Level.ToString() + " " + Message + "\n";return tmp;}public string TraceDetail(){string tmp = Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF") + " " + Level.ToString() + " " + Message + "\n";tmp += this.Trace.ToString() + "\r\n";//StackFrame sf = Trace.GetFrame(0); //tmp += $" Method: {sf.GetMethod()}\r\n";//$" File: {sf.GetFileName()}\r\n" +//$" Line Number: {sf.GetFileLineNumber()}\r\n";return tmp;}public static string TraceDetail(LogContent log){string tmp = log.Occurrence.ToString("yyyy-MM-ddTHH:mm:ss.FFFF") + " " + " " + log.Level.ToString() + ":" + log.Message + "\n";tmp += log.Trace.ToString() + "\r\n";//StackFrame sf = Trace.GetFrame(0); //tmp += $" Method: {sf.GetMethod()}\r\n";//$" File: {sf.GetFileName()}\r\n" +//$" Line Number: {sf.GetFileLineNumber()}\r\n";return tmp;}public string TraceTopFrame(){return this.Trace.GetFrame(0).ToString();}public StackFrame TraceTopStackFrame(){return Trace.GetFrame(0);}public StackFrame TraceBottomStackFrame(){return Trace.GetFrame(this.Trace.FrameCount - 1);}public int GetSize(){//在safe环境中无法使用sizeof(DateTime),sizeof(DateTime)用8字节代替// Each character in a string is 2 bytes (UTF-16 encoding).int total = sizeof(LogLevel) + this.Message.Length * 2 + 8;for (int i = 0; i < this.Trace.FrameCount; i++){StackFrame sf = this.Trace.GetFrame(i);//sf.GetFileLineNumber();sf.GetFileName(); sf.GetMethod().Name; total += sf.ToString().Length * 2;}return total;}public static int GetSize(LogContent log){//在safe环境中无法使用sizeof(DateTime),sizeof(DateTime)用8字节代替// Each character in a string is 2 bytes (UTF-16 encoding).int total = sizeof(LogLevel) + log.Message.Length * 2 + 8;for (int i = 0; i < log.Trace.FrameCount; i++){StackFrame sf = log.Trace.GetFrame(i);//sf.GetFileLineNumber();sf.GetFileName(); sf.GetMethod().Name; total += sf.ToString().Length * 2;}return total;}}public class LogBuffer{protected List<LogContent> buf = new List<LogContent>();public List<LogContent> Buffer { get { return buf; } }public LogBuffer(){buf = new List<LogContent>();}public LogBuffer(List<LogContent> buf){this.buf = buf;}public void Insert(LogContent log){this.buf.Add(log);}public void Insert(LogBuffer log){foreach (var item in log.Buffer){this.buf.Add(item);}}public int LogSize(){int size = 0;foreach (LogContent cnt in this.buf){size += LogContentX.GetSize(cnt);}return size;}}public class LogBufQuery{public List<LogContent> Buffer { get; set; }public void TimeOrderAsc(){Buffer.Sort((x, y) => x.Occurrence.CompareTo(y.Occurrence));}public void TimeOrderDsc(){Buffer.Sort((x, y) => y.Occurrence.CompareTo(x.Occurrence));}public List<LogContent> FilterByLoglevel(LogLevel loglevel){return Buffer.FindAll(log => log.Level == loglevel);}}public struct logstatics{public string item;public string value;public long Timestamp;// 将 UNIX 时间戳转换为 DateTime//DateTime dateTime = DateTimeOffset.FromUnixTimeSeconds(Timestamp).DateTime;public DateTime FromUnixTime(){return DateTimeOffset.FromUnixTimeSeconds(Timestamp).DateTime;}}public class TotalAccessSattistic{private ulong totalAccess;/// <summary>/// 总访问量/// </summary>public ulong TotalAccess{get{return this.totalAccess;}}private void Reset(){ this.totalAccess = 0; }public void StasticAccess(List<LogContent> buf, string flagstr = "HandleClientComm"){foreach (var cnt in buf){if (cnt.Message == flagstr)this.totalAccess++;}}}//将日志写成文本文件,注意在多线程环境下要排除线程互斥。public class NtLog{//private Queue<LogBuffer> Buff = new Queue<LogBuffer>();private Queue<LogContent> buffer = new Queue<LogContent>();public string LogPath { get; }private string curfilepath = string.Empty;private string errorLgFile = string.Empty;  //定义从Exception到Fault这5个层级为Errorprivate 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 NtLog(){this.LogPath = AppDomain.CurrentDomain.BaseDirectory;创建日志文件夹this.LogPath = CreateLogDirectory();MakeLogFileName();maxms = minms = lastms = 0;}public void Enqueue(LogContent log){this.buffer.Enqueue(log);}public void Enqueue(List<LogContent> logs){foreach (LogContent log in logs){this.buffer.Enqueue(log);}}public void Enqueue(LogBuffer logbuf){foreach (LogContent log in logbuf.Buffer){this.buffer.Enqueue(log);}}public void OnLogging(List<LogContent> logs){//#if DEBUG//            TempLog.logging($"查看原始数据。{logs.Count} ");//{logs.First().Message}//#endif//this.Buff.Enqueue(new LogBuffer(logs));this.Enqueue(logs);this.UpdatePathFileName();if (this.IsWriting == false && this.buffer.Count > 0){//LogBuffer Temp = this.Buff.Dequeue();//while (this.Buff.Count > 0)//{//    Temp.Insert(this.Buff.Dequeue());//}WriteLogByThreadV4(this.buffer);}}public void OnLogging(Queue<LogContent> logs){for (int i = 0; i < logs.Count; i++){this.buffer.Enqueue(logs.Dequeue());}this.UpdatePathFileName();if (this.IsWriting == false && this.buffer.Count > 0){//LogBuffer Temp = this.Buff.Dequeue();//while (this.Buff.Count > 0)//{//    Temp.Insert(this.Buff.Dequeue());//}WriteLogByThreadV4(this.buffer);}}public 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;}public 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");}public 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 (var cnt in this.buffer){if (cnt.Level >= LogLevel.Warning)writer.WriteLine(LogContentX.TraceDetail(cnt));}}}//发现它仍然阻塞主线程//注意只有一个线程写,不能多个线程同时写文件。//请注意,Buffer.Remove(cnt) 在循环中可能会导致问题,因为从集合中移除元素会改变集合的大小,从而可能导致迭代器失效。为了避免这个问题,可以先收集需要删除的元素,然后在循环结束后统一删除它们。public void WriteLogByThread(LogBuffer logs){this.watcher.Start();this.IsWriting = true;//#if DEBUG//            TempLog.logging($"BeofreWriteLog。{this.curfilepath} {this.errorLgFile}");//#endif//this.WriteLogFile// 使用Task.Run在后台线程中执行文件写入操作this.task = Task.Run(() =>{//FileStream可以设置成独享锁定模式,防止 线程互斥using (FileStream fs1 = new FileStream(this.curfilepath, FileMode.Append, FileAccess.Write, FileShare.None),fs2 = new FileStream(this.errorLgFile, FileMode.Append, FileAccess.Write, FileShare.None)){using (StreamWriter writer = new StreamWriter(fs1), writer2 = new StreamWriter(fs2)){foreach (var cnt in logs.Buffer){writer.WriteLine(cnt.ToString());if (cnt.Level >= LogLevel.Warning)writer2.WriteLine(LogContentX.TraceDetail(cnt));}}}//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;}//如果没有errlog就不写public void WriteLogByThreadV2(LogBuffer logs){this.watcher.Start();this.IsWriting = true;Queue<LogContent> errlogs = new Queue<LogContent>();//#if DEBUG//            TempLog.logging($"BeofreWriteLog。{this.curfilepath} {this.errorLgFile}");//#endif//this.WriteLogFile// 使用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 logs.Buffer){writer.WriteLine(cnt.ToString());if (cnt.Level >= LogLevel.Warning)errlogs.Enqueue(cnt);}}}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(errlogs.Dequeue().ToString());}}}}//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 WriteLogByThreadV3(Queue<LogContent> queue){this.watcher.Start();this.IsWriting = true;Queue<LogContent> errlogs = new Queue<LogContent>();//#if DEBUG//            TempLog.logging($"BeofreWriteLog。{this.curfilepath} {this.errorLgFile}");//#endif//this.WriteLogFile// 使用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 (queue.Count > 0){var tmp = queue.Dequeue();writer.WriteLine(tmp.ToString());if (tmp.Level >= LogLevel.Warning)errlogs.Enqueue(tmp);}}}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(errlogs.Dequeue().ToString());}}}}//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 WriteLogByThreadV4(Queue<LogContent> queue){this.watcher.Start();this.IsWriting = true;Queue<LogContent> errlogs = new Queue<LogContent>();//#if DEBUG//            TempLog.logging($"BeofreWriteLog。{this.curfilepath} {this.errorLgFile}");//#endif//this.WriteLogFile// 使用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 (queue.Count > 0){var tmp = queue.Dequeue();writer.WriteLine(tmp.ToString());if (tmp.Level >= LogLevel.Warning)errlogs.Enqueue(tmp);}}}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(LogContentX.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;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/69284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka 可靠性探究—副本刨析

Kafka 的多副本机制提升了数据容灾能力。 副本通常分为数据副本与服务副本。数据副本是指在不同的节点上持久化同一份数据&#xff1b;服务副本指多个节点提供同样的服务&#xff0c;每个节点都有能力接收来自外部的请求并进行相应的处理。 1 副本刨析 1.1 相关概念 AR&…

智能化转型2.0:从“工具应用”到“价值重构”

过去几年&#xff0c;“智能化”从一个模糊的概念逐渐成为企业发展的核心议题。2024年&#xff0c;随着生成式AI、大模型、智能体等技术的爆发式落地&#xff0c;中国企业正式迈入智能化转型的2.0时代。这一阶段的核心特征是从单一场景的“工具应用”转向全链条的“价值重构”&…

Unity Dots学习

ISystem和SystemBase的区别 Archetype和Chunk 相同组件的实体放在一起&#xff0c;也就是我们所说的内存块&#xff08;Chunk&#xff09; Chunk有一个大小 https://blog.csdn.net/weixin_40124181/article/details/103716338 如果批量操作的entity都是同一个chunk下的效率会更…

【1】高并发导出场景下,服务器性能瓶颈优化

高并发导出场景下&#xff0c;服务器性能瓶颈通常出现在 CPU、内存、磁盘 I/O 或网络带宽等方面。为了解决这些问题&#xff0c;可以从以下几个方面进行优化&#xff1a; 1. 优化导出逻辑 减少计算复杂度&#xff1a;检查导出逻辑中是否存在不必要的计算或重复操作&#xff0c;…

使用 Axios 获取用户数据并渲染——个人信息设置

目录 1. HTML 部分&#xff08;前端页面结构&#xff09; HTML 结构解析&#xff1a; 2. JavaScript 部分&#xff08;信息渲染逻辑&#xff09; JavaScript 解析&#xff1a; 3. 完整流程 4. 总结 5. 适用场景 本文将介绍如何通过 Axios 从服务器获取用户信息&#xff0…

能否通过蓝牙建立TCP/IP连接来传输数据

前言&#xff1a; 最近在做一个项目时&#xff0c;产生了一个疑问&#xff1a;能否通过蓝牙建立TCP/IP连接来传输数据 查阅了一些文章&#xff0c;可以得出结论&#xff1a;不行 下面是我截取的两篇个人认可的文章的回答&#xff1a; 文章一&#xff1a; 蓝牙是一种短距离无…

C06S02-Docker网络和资源限制

一、Docker网络模式 1. 桥接模式 Docker的默认网络模式&#xff0c;工作在第二层&#xff0c;也就是数据链路层。 启动Docker的时候会在宿主机上创建一个虚拟的网桥&#xff0c;工作方式类似于交换机。创建容器的时候&#xff0c;会分配一个和网桥相同网段的IP地址给容器使用…

生产环境的 MySQL事务隔离级别

MySQL 数据库的默认隔离级别是 RR( 可重复读 )&#xff0c;但是很多大公司把隔离级别改成了 RC(读已提交)&#xff0c;主要原因是为了提高并发和降低死锁概率 为了解决幻读的问题 RR 相比 RC 多了间隙锁( gap lock )和临键锁( next-keylock )。而 RC 中修改数据仅用行锁&#…

Oracle(windows安装遇到的ORA-12545、ORA-12154、ORA-12541、ORA-12514等问题)

其实出现该问题就是监听或者服务没有配好。 G:\xiaowangzhenshuai\software\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMINlistener.ora SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME CLRExtProc)(ORACLE_HOME G:\xiaowangzhenshuai\software\Oracle\product\11.2.0\d…

Mac上搭建k8s环境——Minikube

1、在mac上安装Minikube可执行程序 brew cask install minikub 安装后使用minikube version命令查看版本 2、安装docker环境 brew install --cask --appdir/Applications docker #安装docker open -a Docker #启动docker 3、安装kubectl curl -LO https://storage.g…

OpenAI 实战进阶教程 - 第二节:生成与解析结构化数据:从文本到表格

目标 学习如何使用 OpenAI API 生成结构化数据&#xff08;如 JSON、CSV 格式&#xff09;。掌握解析数据并导出表格文件的技巧&#xff0c;以便适用于不同实际场景。 场景背景 假设你是一名开发人员&#xff0c;需要快速生成一批产品信息列表&#xff08;如名称、价格、描述…

PostgreSQL 中进行数据导入和导出

在数据库管理中&#xff0c;数据的导入和导出是非常常见的操作。特别是在 PostgreSQL 中&#xff0c;提供了多种工具和方法来实现数据的有效管理。无论是备份数据&#xff0c;还是将数据迁移到其他数据库&#xff0c;或是进行数据分析&#xff0c;掌握数据导入和导出的技巧都是…

【Gitlab】虚拟机硬盘文件丢失,通过xx-flat.vmdk恢复方法

前言 由于近期过年回家&#xff0c;为了用电安全直接手动关闭了所有的电源&#xff0c;导致年后回来商上电开机后exsi上的虚拟机出现了问题。显示我的gitlab虚拟机异常。 恢复 开机之后虚拟机异常&#xff0c;通过磁盘浏览发现gitlab服务器下面的虚拟机磁盘文件只有一个xxx-f…

如何在自己mac电脑上私有化部署deep seek

在 Mac 电脑上私有化部署 DeepSeek 的步骤如下&#xff1a; 1. 环境准备 安装 Homebrew&#xff08;如果尚未安装&#xff09;&#xff1a; Homebrew 是 macOS 上的包管理工具&#xff0c;用于安装依赖。 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com…

DeepSeek服务器繁忙问题的原因分析与解决方案

一、引言 随着人工智能技术的飞速发展&#xff0c;DeepSeek 等语言模型在众多领域得到了广泛应用。然而&#xff0c;在春节这段时间的使用过程中&#xff0c;用户常常遭遇服务器繁忙的问题&#xff0c;这不仅影响了用户的使用体验&#xff0c;也在一定程度上限制了模型的推广和…

python的ruff简单使用

Ruff 是一个用 Rust 编写的高性能 Python 静态分析工具和代码格式化工具。它旨在提供快速的代码检查和格式化功能&#xff0c;同时支持丰富的配置选项和与现有工具的兼容性。ruff是用rust实现的python Linter&Formatter。 安装&#xff1a; conda install -c conda-forge…

第16章 Single Thread Execution设计模式(Java高并发编程详解:多线程与系统设计)

简单来说&#xff0c; Single Thread Execution就是采用排他式的操作保证在同一时刻只能有一个线程访问共享资源。 1.机场过安检 1.1非线程安全 先模拟一个非线程安全的安检口类&#xff0c;旅客(线程)分别手持登机牌和身份证接受工作人员的检查&#xff0c;示例代码如所示。…

C# 压缩图片并保存到本地

本文主要介绍如何使用C#将图片进行压缩并保存到本地。 接收一个原始图片的字节数组、需要保存的图片类型、输出路径和图片质量。方法首先将字节数组转换为一个内存流&#xff0c;然后使用Image.FromStream方法将内存流转换为一个Image对象。接下来&#xff0c;方法创建一个编码…

项目练习:重写若依后端报错cannot be cast to com.xxx.model.LoginUser

文章目录 一、情景说明二、解决办法 一、情景说明 在重写若依后端服务的过程中 使用了Redis存放LoginUser对象数据 那么&#xff0c;有存就有取 在取值的时候&#xff0c;报错 二、解决办法 方法1、在TokenService中修改如下 getLoginUser 方法中&#xff1a;LoginUser u…

操作系统和中间件的信息收集

在浏览器中收集操作系统与中间件信息时&#xff0c;主要通过客户端JavaScript&#xff08;用于操作系统/浏览器信息&#xff09;和服务器端脚本&#xff08;用于中间件信息&#xff09;实现。以下是分步指南&#xff1a; 一、客户端操作系统信息收集&#xff08;JavaScript&am…