Skip to content

Commit 59e48e8

Browse files
committed
Added IDisposable to a few components to prevent leaks and added additional failure logging
1 parent add4864 commit 59e48e8

6 files changed

Lines changed: 60 additions & 24 deletions

File tree

src/EventLogExpert/Components/DetailsPane.razor.cs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
using Microsoft.AspNetCore.Components;
1111
using Microsoft.AspNetCore.Components.Web;
1212
using Microsoft.JSInterop;
13+
using Microsoft.Extensions.Logging;
1314
using System.Collections.Immutable;
1415

1516
namespace EventLogExpert.Components;
1617

17-
public sealed partial class DetailsPane
18+
public sealed partial class DetailsPane : IDisposable
1819
{
1920
private bool _hasOpened = false;
2021
private bool _isVisible = false;
@@ -32,6 +33,10 @@ public sealed partial class DetailsPane
3233

3334
[Inject] private ISettingsService Settings { get; init; } = null!;
3435

36+
[Inject] private IFileLogger TraceLogger { get; init; } = null!;
37+
38+
public void Dispose() => SelectedEventSelection.SelectedValueChanged -= OnSelectedEventChanged;
39+
3540
protected override async Task OnAfterRenderAsync(bool firstRender)
3641
{
3742
if (firstRender)
@@ -46,18 +51,7 @@ protected override void OnInitialized()
4651
{
4752
SelectedEventSelection.Select(s => s.SelectedEvents);
4853

49-
SelectedEventSelection.SelectedValueChanged += async (s, selectedEvents) =>
50-
{
51-
SelectedEvent = selectedEvents.LastOrDefault();
52-
53-
if (SelectedEvent is null) { return; }
54-
55-
await SelectedEvent.ResolveXml();
56-
57-
if (!_hasOpened || Settings.ShowDisplayPaneOnSelectionChange) { _isVisible = true; }
58-
59-
StateHasChanged();
60-
};
54+
SelectedEventSelection.SelectedValueChanged += OnSelectedEventChanged;
6155

6256
base.OnInitialized();
6357
}
@@ -80,6 +74,26 @@ private void HandleKeyDownXml(KeyboardEventArgs e)
8074
}
8175
}
8276

77+
private async void OnSelectedEventChanged(object? sender, ImmutableList<DisplayEventModel> selectedEvents)
78+
{
79+
try
80+
{
81+
SelectedEvent = selectedEvents.LastOrDefault();
82+
83+
if (SelectedEvent is null) { return; }
84+
85+
await SelectedEvent.ResolveXml();
86+
87+
if (!_hasOpened || Settings.ShowDisplayPaneOnSelectionChange) { _isVisible = true; }
88+
89+
await InvokeAsync(StateHasChanged);
90+
}
91+
catch (Exception e)
92+
{
93+
TraceLogger.Trace($"Failed to handle selected event change: {e}", LogLevel.Error);
94+
}
95+
}
96+
8397
private void ToggleMenu()
8498
{
8599
if (!_hasOpened) { _hasOpened = true; }

src/EventLogExpert/Components/FilterPane.razor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace EventLogExpert.Components;
1616

17-
public sealed partial class FilterPane
17+
public sealed partial class FilterPane : IDisposable
1818
{
1919
private readonly FilterDateModel _model = new();
2020

@@ -36,6 +36,8 @@ public sealed partial class FilterPane
3636

3737
[Inject] private ISettingsService Settings { get; init; } = null!;
3838

39+
public void Dispose() => Settings.TimeZoneChanged -= UpdateFilterDateTimeZone;
40+
3941
protected override void OnInitialized()
4042
{
4143
SubscribeToAction<FilterPaneAction.ClearAllFilters>(action => { _canEditDate = false; });

src/EventLogExpert/MainPage.xaml.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ await MainThread.InvokeOnMainThreadAsync(() =>
116116

117117
public void Dispose()
118118
{
119+
_settings.CopyTypeChanged -= SetCopyKeyboardAccelerator;
120+
119121
_cancellationTokenSource.Cancel();
120122
_cancellationTokenSource.Dispose();
121123
}
@@ -447,7 +449,7 @@ private async Task ProcessCommandLine()
447449
{
448450
switch (arg)
449451
{
450-
case not null when arg.EndsWith(".evtx"):
452+
case not null when arg.EndsWith(".evtx", StringComparison.OrdinalIgnoreCase):
451453
await OpenLog(arg, PathType.FilePath);
452454
break;
453455
}

src/EventLogExpert/Shared/Components/DebugLogModal.razor.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@
77

88
namespace EventLogExpert.Shared.Components;
99

10-
public partial class DebugLogModal
10+
public partial class DebugLogModal : IDisposable
1111
{
1212
private readonly List<string> _data = [];
1313

1414
[Inject] private IFileLogger TraceLogger { get; set; } = null!;
1515

16+
public void Dispose()
17+
{
18+
TraceLogger.DebugLogLoaded -= OnDebugLogLoaded;
19+
GC.SuppressFinalize(this);
20+
}
21+
1622
protected internal override async Task Open()
1723
{
1824
await Refresh();

src/EventLogExpert/Shared/Components/Filters/FilterGroup.razor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ public sealed partial class FilterGroup
2525

2626
private void AddFilter() => Dispatcher.Dispatch(new FilterGroupAction.AddFilter(Group.Id));
2727

28-
private void ApplyFilters()
28+
private async Task ApplyFilters()
2929
{
3030
Dispatcher.Dispatch(new FilterPaneAction.ApplyFilterGroup(Group));
31-
InvokeAsync(Parent.Close);
31+
await InvokeAsync(Parent.Close);
3232
}
3333

3434
private void CopyGroup() => Clipboard.SetTextAsync(Group.Filters.Count > 1 ?

src/EventLogExpert/Shared/Components/SettingsModal.razor.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace EventLogExpert.Shared.Components;
1616

17-
public sealed partial class SettingsModal
17+
public sealed partial class SettingsModal : IDisposable
1818
{
1919
private readonly List<(string name, bool isEnabled, bool hasChanged)> _databases = [];
2020

@@ -40,6 +40,8 @@ public sealed partial class SettingsModal
4040

4141
[Inject] private IFileLogger TraceLogger { get; init; } = null!;
4242

43+
public void Dispose() => Settings.Loaded -= OnSettingsLoaded;
44+
4345
protected internal override async Task Close()
4446
{
4547
if (_databaseRemoved)
@@ -84,22 +86,32 @@ private async Task ImportDatabase()
8486

8587
Directory.CreateDirectory(FileLocationOptions.DatabasePath);
8688

89+
List<string> importedFiles = [];
90+
8791
foreach (var item in result)
8892
{
89-
if (item?.FileName is null) { continue; }
93+
if (string.IsNullOrEmpty(item?.FileName) || string.IsNullOrEmpty(item.FullPath)) { continue; }
9094

9195
var destination = Path.Join(FileLocationOptions.DatabasePath, item.FileName);
9296
File.Copy(item.FullPath, destination, true);
9397

94-
if (Path.GetExtension(destination) != ".zip") { continue; }
98+
importedFiles.Add(item.FileName);
99+
100+
if (!Path.GetExtension(destination).Equals(".zip", StringComparison.OrdinalIgnoreCase)) { continue; }
95101

96102
await ZipFile.ExtractToDirectoryAsync(destination, FileLocationOptions.DatabasePath, overwriteFiles: true);
97103
File.Delete(destination);
98104
}
99105

100-
var message = result.Length > 1 ?
101-
$"{result.Length} databases have successfully been imported" :
102-
$"{result[0]?.FileName ?? "Database"} has successfully been imported";
106+
if (importedFiles.Count == 0)
107+
{
108+
await AlertDialogService.ShowAlert("Import Failed", "No valid database files were selected.", "OK");
109+
return;
110+
}
111+
112+
var message = importedFiles.Count > 1 ?
113+
$"{importedFiles.Count} databases have successfully been imported" :
114+
$"{importedFiles[0]} has successfully been imported";
103115

104116
await AlertDialogService.ShowAlert("Import Successful", message, "OK");
105117

0 commit comments

Comments
 (0)