2024-09-20 10:50:32 +08:00
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
using System.IO;
|
2024-08-05 10:11:58 +08:00
|
|
|
|
using System.Text;
|
2024-09-21 10:06:44 +08:00
|
|
|
|
using System.Threading.Channels;
|
2024-08-05 10:11:58 +08:00
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
namespace Serein.NodeFlow.Tool
|
2024-08-05 10:11:58 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2024-10-20 12:10:57 +08:00
|
|
|
|
/// 捕获Console输出
|
2024-08-05 10:11:58 +08:00
|
|
|
|
/// </summary>
|
2024-09-20 10:50:32 +08:00
|
|
|
|
public class LogTextWriter : TextWriter
|
2024-08-05 10:11:58 +08:00
|
|
|
|
{
|
2024-09-21 10:06:44 +08:00
|
|
|
|
private readonly Action<string> logAction; // 更新日志UI的委托
|
|
|
|
|
|
private readonly StringWriter stringWriter = new(); // 缓存日志内容
|
|
|
|
|
|
private readonly Channel<string> logChannel = Channel.CreateUnbounded<string>(); // 日志管道
|
2024-10-20 12:10:57 +08:00
|
|
|
|
//private int writeCount = 0; // 写入计数器
|
|
|
|
|
|
//private const int maxWrites = 500; // 写入最大计数
|
2024-09-20 10:50:32 +08:00
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 定义输出委托与清除输出内容委托
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="logAction"></param>
|
|
|
|
|
|
public LogTextWriter(Action<string> logAction)
|
2024-09-20 10:50:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
this.logAction = logAction;
|
2024-09-21 10:06:44 +08:00
|
|
|
|
|
|
|
|
|
|
// 异步启动日志处理任务,不阻塞主线程
|
|
|
|
|
|
Task.Run(ProcessLogQueueAsync);
|
2024-09-20 10:50:32 +08:00
|
|
|
|
}
|
2024-08-05 10:11:58 +08:00
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 编码类型
|
|
|
|
|
|
/// </summary>
|
2024-08-05 10:11:58 +08:00
|
|
|
|
public override Encoding Encoding => Encoding.UTF8;
|
|
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
|
2024-08-05 10:11:58 +08:00
|
|
|
|
public override void Write(char value)
|
|
|
|
|
|
{
|
|
|
|
|
|
stringWriter.Write(value);
|
|
|
|
|
|
if (value == '\n')
|
|
|
|
|
|
{
|
2024-09-20 10:50:32 +08:00
|
|
|
|
EnqueueLog();
|
2024-08-05 10:11:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void Write(string? value)
|
|
|
|
|
|
{
|
2024-09-20 10:50:32 +08:00
|
|
|
|
if (string.IsNullOrWhiteSpace(value)) return;
|
2024-08-05 10:11:58 +08:00
|
|
|
|
stringWriter.Write(value);
|
|
|
|
|
|
if (value.Contains('\n'))
|
|
|
|
|
|
{
|
2024-09-20 10:50:32 +08:00
|
|
|
|
EnqueueLog();
|
2024-08-05 10:11:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void WriteLine(string? value)
|
|
|
|
|
|
{
|
2024-09-20 10:50:32 +08:00
|
|
|
|
if (string.IsNullOrWhiteSpace(value)) return;
|
2024-08-05 10:11:58 +08:00
|
|
|
|
stringWriter.WriteLine(value);
|
2024-09-20 10:50:32 +08:00
|
|
|
|
EnqueueLog();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将日志加入通道
|
|
|
|
|
|
/// </summary>
|
2024-09-20 10:50:32 +08:00
|
|
|
|
private void EnqueueLog()
|
|
|
|
|
|
{
|
2024-09-21 10:06:44 +08:00
|
|
|
|
var log = stringWriter.ToString();
|
2024-08-05 10:11:58 +08:00
|
|
|
|
stringWriter.GetStringBuilder().Clear();
|
2024-09-21 10:06:44 +08:00
|
|
|
|
if (!logChannel.Writer.TryWrite(log))
|
2024-09-20 10:50:32 +08:00
|
|
|
|
{
|
2024-09-21 10:06:44 +08:00
|
|
|
|
// 如果写入失败(不太可能),则直接丢弃日志或处理
|
2024-09-20 10:50:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步处理日志队列
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
2024-09-21 10:06:44 +08:00
|
|
|
|
private async Task ProcessLogQueueAsync()
|
2024-09-20 10:50:32 +08:00
|
|
|
|
{
|
2024-09-21 10:06:44 +08:00
|
|
|
|
await foreach (var log in logChannel.Reader.ReadAllAsync()) // 异步读取日志通道
|
|
|
|
|
|
{
|
|
|
|
|
|
logAction?.Invoke(log); // 执行日志写入到UI的委托
|
|
|
|
|
|
|
2024-10-20 12:10:57 +08:00
|
|
|
|
//writeCount++;
|
|
|
|
|
|
//if (writeCount >= maxWrites)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// writeCount = 0; // 重置计数器
|
|
|
|
|
|
//}
|
2024-09-21 10:06:44 +08:00
|
|
|
|
}
|
2024-09-20 10:50:32 +08:00
|
|
|
|
}
|
2024-08-05 10:11:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|