Fix bug where event viewer may crash from a race condition, resolves #4

This commit is contained in:
BlossomiShymae
2024-08-17 16:25:37 -05:00
parent 7550102406
commit 79fd79c01d
2 changed files with 50 additions and 16 deletions

View File

@@ -18,6 +18,8 @@ namespace Needlework.Net.Desktop.ViewModels
public partial class WebsocketViewModel : PageBase public partial class WebsocketViewModel : PageBase
{ {
public ObservableCollection<string> EventLog { get; } = []; public ObservableCollection<string> EventLog { get; } = [];
public SemaphoreSlim EventLogLock { get; } = new(1, 1);
[NotifyPropertyChangedFor(nameof(FilteredEventLog))] [NotifyPropertyChangedFor(nameof(FilteredEventLog))]
[ObservableProperty] private string _search = string.Empty; [ObservableProperty] private string _search = string.Empty;
[ObservableProperty] private bool _isAttach = true; [ObservableProperty] private bool _isAttach = true;
@@ -94,12 +96,16 @@ namespace Needlework.Net.Desktop.ViewModels
private void OnMessage(EventMessage message) private void OnMessage(EventMessage message)
{ {
Avalonia.Threading.Dispatcher.UIThread.Invoke(() => Avalonia.Threading.Dispatcher.UIThread.Invoke(async () =>
{ {
if (!IsAttach) return; if (!IsAttach) return;
var line = $"{DateTime.Now:HH:mm:ss.fff} {message.Data?.EventType.ToUpper()} {message.Data?.Uri}"; var line = $"{DateTime.Now:HH:mm:ss.fff} {message.Data?.EventType.ToUpper()} {message.Data?.Uri}";
Trace.WriteLine($"Message: {line}"); Trace.WriteLine($"Message: {line}");
await EventLogLock.WaitAsync();
try
{
if (EventLog.Count < 1000) if (EventLog.Count < 1000)
{ {
EventLog.Add(line); EventLog.Add(line);
@@ -114,6 +120,11 @@ namespace Needlework.Net.Desktop.ViewModels
EventLog.Add(line); EventLog.Add(line);
_events[line] = message; _events[line] = message;
} }
}
finally
{
EventLogLock.Release();
}
}); });
} }
} }

View File

@@ -7,6 +7,7 @@ using CommunityToolkit.Mvvm.Messaging;
using Needlework.Net.Desktop.Extensions; using Needlework.Net.Desktop.Extensions;
using Needlework.Net.Desktop.Messages; using Needlework.Net.Desktop.Messages;
using Needlework.Net.Desktop.ViewModels; using Needlework.Net.Desktop.ViewModels;
using System;
using TextMateSharp.Grammars; using TextMateSharp.Grammars;
namespace Needlework.Net.Desktop.Views; namespace Needlework.Net.Desktop.Views;
@@ -14,6 +15,8 @@ namespace Needlework.Net.Desktop.Views;
public partial class WebsocketView : UserControl, IRecipient<ResponseUpdatedMessage> public partial class WebsocketView : UserControl, IRecipient<ResponseUpdatedMessage>
{ {
private TextEditor? _responseEditor; private TextEditor? _responseEditor;
public WebsocketViewModel? _viewModel;
private ListBox? _viewer;
public WebsocketView() public WebsocketView()
{ {
@@ -29,9 +32,9 @@ public partial class WebsocketView : UserControl, IRecipient<ResponseUpdatedMess
{ {
base.OnApplyTemplate(e); base.OnApplyTemplate(e);
var vm = (WebsocketViewModel)DataContext!; _viewModel = (WebsocketViewModel)DataContext!;
var viewer = this.FindControl<ListBox>("EventViewer"); _viewer = this.FindControl<ListBox>("EventViewer");
vm.EventLog.CollectionChanged += (s, e) => { if (vm.IsTail) viewer!.ScrollIntoView(vm.EventLog.Count - 1); }; _viewModel.EventLog.CollectionChanged += EventLog_CollectionChanged; ;
_responseEditor = this.FindControl<TextEditor>("ResponseEditor"); _responseEditor = this.FindControl<TextEditor>("ResponseEditor");
_responseEditor?.ApplyJsonEditorSettings(); _responseEditor?.ApplyJsonEditorSettings();
@@ -41,6 +44,26 @@ public partial class WebsocketView : UserControl, IRecipient<ResponseUpdatedMess
OnBaseThemeChanged(Application.Current!.ActualThemeVariant); OnBaseThemeChanged(Application.Current!.ActualThemeVariant);
} }
private void EventLog_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Avalonia.Threading.Dispatcher.UIThread.Post(async () =>
{
if (_viewModel!.IsTail)
{
await _viewModel.EventLogLock.WaitAsync();
try
{
_viewer!.ScrollIntoView(_viewModel.EventLog.Count - 1);
}
catch (InvalidOperationException) { }
finally
{
_viewModel.EventLogLock.Release();
}
}
});
}
private void OnBaseThemeChanged(ThemeVariant currentTheme) private void OnBaseThemeChanged(ThemeVariant currentTheme)
{ {