Optimize and improve message function

Test_AvaloniaEdit
2dust 2025-09-26 11:19:40 +08:00
parent 76dc14ee45
commit e51b923d82
5 changed files with 54 additions and 51 deletions

View File

@ -10,10 +10,9 @@ namespace ServiceLib.ViewModels;
public class MsgViewModel : MyReactiveObject public class MsgViewModel : MyReactiveObject
{ {
private readonly ConcurrentQueue<string> _queueMsg = new(); private readonly ConcurrentQueue<string> _queueMsg = new();
private readonly StringBuilder _msgBuilder = new(); private volatile bool _lastMsgFilterNotAvailable;
private readonly int _numMaxMsg = 500; private int _showLock = 0; // 0 = unlocked, 1 = locked
private bool _lastMsgFilterNotAvailable; public int NumMaxMsg { get; } = 50;
private bool _blLockShow = false;
[Reactive] [Reactive]
public string MsgFilter { get; set; } public string MsgFilter { get; set; }
@ -35,12 +34,12 @@ public class MsgViewModel : MyReactiveObject
this.WhenAnyValue( this.WhenAnyValue(
x => x.AutoRefresh, x => x.AutoRefresh,
y => y == true) y => y == true)
.Subscribe(c => { _config.MsgUIItem.AutoRefresh = AutoRefresh; }); .Subscribe(c => _config.MsgUIItem.AutoRefresh = AutoRefresh);
AppEvents.SendMsgViewRequested AppEvents.SendMsgViewRequested
.AsObservable() .AsObservable()
//.ObserveOn(RxApp.MainThreadScheduler) //.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async content => await AppendQueueMsg(content)); .Subscribe(content => _ = AppendQueueMsg(content));
} }
private async Task AppendQueueMsg(string msg) private async Task AppendQueueMsg(string msg)
@ -49,36 +48,38 @@ public class MsgViewModel : MyReactiveObject
{ {
return; return;
} }
_ = EnqueueQueueMsg(msg);
if (_blLockShow) EnqueueQueueMsg(msg);
{
return;
}
if (!_config.UiItem.ShowInTaskbar) if (!_config.UiItem.ShowInTaskbar)
{ {
return; return;
} }
_blLockShow = true; if (Interlocked.CompareExchange(ref _showLock, 1, 0) != 0)
_msgBuilder.Clear();
//foreach (var it in _queueMsg)
//{
// _msgBuilder.Append(it);
//}
while (_queueMsg.TryDequeue(out var line))
{ {
_msgBuilder.Append(line); return;
} }
try
{
await Task.Delay(500).ConfigureAwait(false);
await _updateView?.Invoke(EViewAction.DispatcherShowMsg, _msgBuilder.ToString()); var sb = new StringBuilder();
while (_queueMsg.TryDequeue(out var line))
{
sb.Append(line);
}
_blLockShow = false; await _updateView?.Invoke(EViewAction.DispatcherShowMsg, sb.ToString());
}
finally
{
Interlocked.Exchange(ref _showLock, 0);
}
} }
private async Task EnqueueQueueMsg(string msg) private void EnqueueQueueMsg(string msg)
{ {
//filter msg //filter msg
if (MsgFilter.IsNotEmpty() && !_lastMsgFilterNotAvailable) if (MsgFilter.IsNotEmpty() && !_lastMsgFilterNotAvailable)
@ -97,26 +98,17 @@ public class MsgViewModel : MyReactiveObject
} }
} }
//Enqueue
if (_queueMsg.Count > _numMaxMsg)
{
for (int k = 0; k < _queueMsg.Count - _numMaxMsg; k++)
{
_queueMsg.TryDequeue(out _);
}
}
_queueMsg.Enqueue(msg); _queueMsg.Enqueue(msg);
if (!msg.EndsWith(Environment.NewLine)) if (!msg.EndsWith(Environment.NewLine))
{ {
_queueMsg.Enqueue(Environment.NewLine); _queueMsg.Enqueue(Environment.NewLine);
} }
await Task.CompletedTask;
} }
public void ClearMsg() //public void ClearMsg()
{ //{
_queueMsg.Clear(); // _queueMsg.Clear();
} //}
private void DoMsgFilter() private void DoMsgFilter()
{ {

View File

@ -5,6 +5,7 @@ using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Styling; using Avalonia.Styling;
using AvaloniaEdit;
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Semi.Avalonia; using Semi.Avalonia;
@ -112,7 +113,8 @@ public class ThemeSettingViewModel : MyReactiveObject
x.OfType<ContextMenu>(), x.OfType<ContextMenu>(),
x.OfType<DataGridRow>(), x.OfType<DataGridRow>(),
x.OfType<ListBoxItem>(), x.OfType<ListBoxItem>(),
x.OfType<HeaderedContentControl>() x.OfType<HeaderedContentControl>(),
x.OfType<TextEditor>()
)); ));
style.Add(new Setter() style.Add(new Setter()
{ {
@ -153,7 +155,8 @@ public class ThemeSettingViewModel : MyReactiveObject
x.OfType<DataGridRow>(), x.OfType<DataGridRow>(),
x.OfType<ListBoxItem>(), x.OfType<ListBoxItem>(),
x.OfType<HeaderedContentControl>(), x.OfType<HeaderedContentControl>(),
x.OfType<WindowNotificationManager>() x.OfType<WindowNotificationManager>(),
x.OfType<TextEditor>()
)); ));
style.Add(new Setter() style.Add(new Setter()
{ {

View File

@ -75,7 +75,8 @@
Name="txtMsg" Name="txtMsg"
Margin="{StaticResource Margin8}" Margin="{StaticResource Margin8}"
IsReadOnly="True" IsReadOnly="True"
VerticalScrollBarVisibility="Auto"> VerticalScrollBarVisibility="Auto"
WordWrap="True">
<avaloniaEdit:TextEditor.ContextFlyout> <avaloniaEdit:TextEditor.ContextFlyout>
<MenuFlyout> <MenuFlyout>
<MenuItem <MenuItem

View File

@ -1,5 +1,4 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using Avalonia.Threading; using Avalonia.Threading;
@ -10,12 +9,9 @@ namespace v2rayN.Desktop.Views;
public partial class MsgView : ReactiveUserControl<MsgViewModel> public partial class MsgView : ReactiveUserControl<MsgViewModel>
{ {
private readonly ScrollViewer _scrollViewer;
public MsgView() public MsgView()
{ {
InitializeComponent(); InitializeComponent();
_scrollViewer = this.FindControl<ScrollViewer>("msgScrollViewer");
ViewModel = new MsgViewModel(UpdateViewHandler); ViewModel = new MsgViewModel(UpdateViewHandler);
@ -44,19 +40,23 @@ public partial class MsgView : ReactiveUserControl<MsgViewModel>
private void ShowMsg(object msg) private void ShowMsg(object msg)
{ {
// txtMsg.Text = msg.ToString(); if (txtMsg.Document.LineCount > ViewModel?.NumMaxMsg)
txtMsg.AppendText(msg.ToString()); {
ClearMsg();
}
if (togScrollToEnd.IsChecked ?? true) if (togScrollToEnd.IsChecked ?? true)
{ {
//txtMsg.ScrollToLine(txtMsg.Document.LineCount);
txtMsg.ScrollToEnd(); txtMsg.ScrollToEnd();
_scrollViewer?.ScrollToEnd();
} }
txtMsg.AppendText(msg.ToString());
} }
public void ClearMsg() public void ClearMsg()
{ {
ViewModel?.ClearMsg(); txtMsg.Clear();
txtMsg.Text = ""; txtMsg.AppendText("----- Message cleared -----\n");
} }
private void menuMsgViewSelectAll_Click(object? sender, RoutedEventArgs e) private void menuMsgViewSelectAll_Click(object? sender, RoutedEventArgs e)

View File

@ -48,18 +48,25 @@ public partial class MsgView
private void ShowMsg(object msg) private void ShowMsg(object msg)
{ {
txtMsg.BeginChange(); txtMsg.BeginChange();
txtMsg.Text = msg.ToString();
if (txtMsg.LineCount > ViewModel?.NumMaxMsg)
{
ClearMsg();
}
txtMsg.AppendText(msg.ToString());
if (togScrollToEnd.IsChecked ?? true) if (togScrollToEnd.IsChecked ?? true)
{ {
txtMsg.ScrollToEnd(); txtMsg.ScrollToEnd();
} }
txtMsg.EndChange(); txtMsg.EndChange();
} }
public void ClearMsg() public void ClearMsg()
{ {
ViewModel?.ClearMsg();
txtMsg.Clear(); txtMsg.Clear();
txtMsg.AppendText("----- Message cleared -----\n");
} }
private void menuMsgViewSelectAll_Click(object sender, System.Windows.RoutedEventArgs e) private void menuMsgViewSelectAll_Click(object sender, System.Windows.RoutedEventArgs e)