using BDU.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 BDU.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 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); } } } } }