BDU/ATS/Views/LogArea.xaml.cs

96 lines
3.0 KiB
C#

using ATS.Tools;
using PropertyChanged;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
namespace ATS.Views
{
public partial class LogArea : UserControl
{
// 日志配置常量
private const int MaxLogCount = 2000; // 最大日志条数
private const int PurgeThreshold = 1500; // 触发清理的阈值
private const int CleanupBatchSize = 100;// 添加批量清理阈值
// 异步处理状态标志
private bool _purgePending = false;
public ObservableCollection<LogEntry> LogEntries { get; } = [];
public LogArea()
{
InitializeComponent();
DataContext = this;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Log.Dispatcher = Dispatcher;
Log.LogAdded += OnLogAdded;
}
private void OnLogAdded(string message, SolidColorBrush color, int depth = 0)
{
Dispatcher.Invoke(() =>
{
// 添加新日志
LogEntries.Add(new LogEntry(message, color, depth));
// 检查是否需要清理旧日志
if (LogEntries.Count > PurgeThreshold && !_purgePending)
{
_purgePending = true;
Dispatcher.BeginInvoke(new Action(PurgeExcessLogs), DispatcherPriority.Background);
}
// 延迟滚动到最新条目
Dispatcher.BeginInvoke(new Action(() =>
{
if (LogListView.Items.Count > 0)
{
try
{
LogListView.ScrollIntoView(LogListView.Items[LogListView.Items.Count - 1]);
}
catch (Exception ex)
{
Debug.WriteLine($"滚动错误: {ex.Message}");
}
}
}), DispatcherPriority.ContextIdle);
});
}
private void PurgeExcessLogs()
{
try
{
int excessCount = LogEntries.Count - MaxLogCount;
if (excessCount <= 0) return;
int removeCount = Math.Min(excessCount, CleanupBatchSize);
for (int i = 0; i < removeCount; i++)
{
LogEntries.RemoveAt(0);
}
}
finally
{
_purgePending = LogEntries.Count > PurgeThreshold;
if (_purgePending)
{
// 添加延迟防止递归过深
Dispatcher.BeginInvoke(new Action(PurgeExcessLogs), DispatcherPriority.Background, null);
}
}
}
}
}