Skip to content

Commit 4074963

Browse files
committed
load logs asynchronous
1 parent 076289c commit 4074963

File tree

6 files changed

+87
-48
lines changed

6 files changed

+87
-48
lines changed

src/WEventViewer/MainWindow.axaml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,32 @@
1111
<vm:MainWindowViewModel></vm:MainWindowViewModel>
1212
</Design.DataContext>
1313

14-
<StackPanel Orientation="Vertical">
15-
<Menu DockPanel.Dock="Top">
14+
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
15+
<Menu DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1">
1616
<MenuItem Header="_File">
1717
<MenuItem Header="_Open" Command="{Binding OpenCommand}"/>
18+
<MenuItem Header="_Close" Command="{Binding CloseCommand}"/>
1819
</MenuItem>
1920
<MenuItem Header="_About"/>
2021
</Menu>
21-
<ScrollViewer>
22+
<ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20">
2223
<DataGrid
2324
BorderBrush="Black"
2425
Margin="20"
2526
BorderThickness="1"
26-
IsReadOnly="True" ItemsSource="{Binding LogRecords}" VerticalAlignment="Stretch" MaxHeight="500">
27+
IsReadOnly="True" ItemsSource="{Binding LogRecords}" VerticalAlignment="Stretch" MaxHeight="500" MinHeight="200">
2728
<DataGrid.Columns>
29+
<DataGridTextColumn Header="TimeCreated" Binding="{Binding TimeCreated}"/>
2830
<DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
2931
<DataGridTextColumn Header="LogName" Binding="{Binding LogName}"/>
3032
<DataGridTextColumn Header="Description" Binding="{Binding Formatted}"/>
3133
</DataGrid.Columns>
3234
<DataGrid.RowHeight>50</DataGrid.RowHeight>
3335
</DataGrid>
3436
</ScrollViewer>
35-
<StackPanel Orientation="Horizontal">
36-
<Label Content="{Binding LogCount}"/>
37+
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="20">
38+
<Label Content="{Binding LogCount,Mode=OneWay}"/>
39+
<Label Content="{Binding LoadStatus,Mode=OneWay}"/>
3740
</StackPanel>
3841
</StackPanel>
3942
</Window>

src/WEventViewer/MainWindow.axaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,6 @@ public MainWindow()
3131
var dlg = new ErrorWindow() { DataContext = vm };
3232
await dlg.ShowDialog(mw);
3333
});
34+
WeakReferenceMessenger.Default.Register<MainWindow, MainWindowCloseMessage>(this, (w, msg) => w.Close());
3435
}
3536
}

src/WEventViewer/Model/EventLogRepository.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
using System.Diagnostics.Eventing.Reader;
88
using System.Threading;
99
using Microsoft.CodeAnalysis.CSharp.Syntax;
10-
using System.Collections.ObjectModel;
1110
using System.Diagnostics;
11+
using System.Runtime.CompilerServices;
12+
using System.Collections.ObjectModel;
13+
using R3.Collections;
1214

1315
namespace WEventViewer.Model
1416
{
@@ -108,39 +110,39 @@ public void Clear()
108110
records.Clear();
109111
}
110112
static readonly DiagnosticListener _DS = new DiagnosticListener(nameof(EventLogRepository));
111-
public async Task Load(string logName, PathType pathType, string? query, CancellationToken token, IProgress<long> progress)
113+
public async Task Load(string logName, PathType pathType, string? query, CancellationToken token, Action<IList<LogRecord>> dispatch)
112114
{
113115
using var evreader = new EventLogReader(new EventLogQuery(logName, pathType, query));
116+
Clear();
114117
long count = 0;
118+
List<LogRecord> lst = [];
119+
await Task.Delay(10).ConfigureAwait(false);
115120
while (!token.IsCancellationRequested)
116121
{
117-
await Task.Yield();
118122
using var record = evreader.ReadEvent();
119123
try
120124
{
121125
if (record == null)
122126
{
123127
break;
124128
}
125-
records.Add(record.ToLogRecord());
129+
lst.Add(record.ToLogRecord());
126130
count++;
127131
if ((count & 0xff) == 0)
128132
{
129-
progress?.Report(count);
133+
dispatch(lst);
134+
lst.Clear();
130135
}
131136
}
132137
catch (Exception ex)
133138
{
134139
_DS.Write("Error", new { Exception = ex, LogRecordDescription = record.FormatDescription() });
135-
throw;
136-
}
137-
if(records.Count >= 1000)
138-
{
139-
break;
140140
}
141141
}
142-
143-
progress?.Report(count);
142+
if (lst.Count > 0)
143+
{
144+
dispatch(lst);
145+
}
144146
}
145147
}
146148
}

src/WEventViewer/OpenLogWindow.axaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:vm="using:WEventViewer.ViewModel"
66
xmlns:local="using:WEventViewer"
7-
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
7+
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
88
x:Class="WEventViewer.OpenLogWindow"
99
x:DataType="vm:OpenLogWindowViewModel"
1010
Title="OpenLogWindow">
@@ -14,14 +14,14 @@
1414
<Window.Resources>
1515
<vm:PathTypeValueConverter x:Key="PathTypeConverter"/>
1616
</Window.Resources>
17-
<StackPanel HorizontalAlignment="Stretch">
18-
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
17+
<StackPanel HorizontalAlignment="Stretch" Margin="20">
18+
<StackPanel Orientation="Horizontal">
1919
<Label Content="LogName" Margin="10,10,10,10" HorizontalAlignment="Left"/>
20-
<TextBox Margin="10,10,10,10" Padding="0,0,0,0" HorizontalAlignment="Stretch" Text="{Binding LogName, Mode=TwoWay}"/>
20+
<TextBox HorizontalContentAlignment="Stretch" Margin="10,10,10,10" Padding="0,0,0,0" HorizontalAlignment="Right" Text="{Binding LogName, Mode=TwoWay}" MinWidth="200"/>
2121
</StackPanel>
2222
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
2323
<Label Content="PathType" Margin="10,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Center"/>
24-
<TextBox Margin="10,10,10,10" Padding="10,0,10,10" HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding Path=PathType, Mode=TwoWay,Converter={StaticResource PathTypeConverter}}"/>
24+
<TextBox Margin="10,10,10,10" Padding="10,0,10,10" TextAlignment="Center" Text="{Binding Path=PathType, Mode=TwoWay,Converter={StaticResource PathTypeConverter}}"/>
2525
</StackPanel>
2626
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
2727
<Button Content="OK" Command="{ Binding OkCommand }"/>

src/WEventViewer/ViewModel/MainWindowViewModel.cs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using Avalonia;
1818
using System.ComponentModel;
1919
using System.Security.Cryptography.X509Certificates;
20+
using Avalonia.Threading;
2021

2122

2223
namespace WEventViewer.ViewModel
@@ -27,55 +28,86 @@ class OpenLogRequest
2728
public PathType PathType { get; set; }
2829
}
2930
record class LoadLogMessage(string logName, PathType pathType);
31+
record class MainWindowCloseMessage();
3032
internal class MainWindowViewModel : ObservableRecipient
3133
{
3234
EventLogRepository _EventLogRepository;
35+
Task LoadTask;
3336
public MainWindowViewModel()
3437
{
38+
LoadTask = Task.CompletedTask;
3539
_Progress = new Progress<long>(l =>
3640
{
37-
_LogCount = l;
41+
Dispatcher.UIThread.Invoke(() =>
42+
{
43+
OnPropertyChanged(nameof(LogCount));
44+
OnPropertyChanged(nameof(LogRecords));
45+
});
3846
});
3947
_EventLogRepository = new EventLogRepository();
40-
_EventLogRepository.Records.CollectionChanged += Records_CollectionChanged;
48+
//_EventLogRepository.Records.CollectionChanged;
4149
OpenCommand = new RelayCommand(() =>
4250
{
51+
LoadStatus = "Loading";
52+
OnPropertyChanged(nameof(LoadStatus));
4353
WeakReferenceMessenger.Default.Send<OpenLogRequest>(new OpenLogRequest());
44-
});
45-
WeakReferenceMessenger.Default.Register<MainWindowViewModel, LoadLogMessage>(this, async (vm, msg) =>
54+
}, () => LoadTask == null || LoadTask.IsCompleted);
55+
WeakReferenceMessenger.Default.Register<MainWindowViewModel, LoadLogMessage>(this, (vm, msg) =>
4656
{
47-
try
48-
{
49-
await _EventLogRepository.Load(msg.logName, msg.pathType, null, default, _Progress);
50-
}
51-
catch (Exception ex)
57+
LoadTask = _EventLogRepository.Load(msg.logName, msg.pathType, null, default, (lst) =>
5258
{
53-
WeakReferenceMessenger.Default.Send(new OpenErrorLogWindow(ex.ToString()));
54-
}
59+
Dispatcher.UIThread.Invoke(() =>
60+
{
61+
foreach (var item in lst)
62+
{
63+
_EventLogRepository.Records.Add(item);
64+
}
65+
OnPropertyChanged(nameof(LogCount));
66+
OnPropertyChanged(nameof(LogRecords));
67+
});
68+
})
69+
.ContinueWith(t =>
70+
{
71+
if (t.IsFaulted)
72+
{
73+
WeakReferenceMessenger.Default.Send(new OpenErrorLogWindow(t.Exception.ToString()));
74+
}
75+
Dispatcher.UIThread.Invoke(() =>
76+
{
77+
LoadStatus = "Complete";
78+
OnPropertyChanged(nameof(LoadStatus));
79+
});
80+
});
5581
});
82+
CloseCommand = new RelayCommand(() => WeakReferenceMessenger.Default.Send(new MainWindowCloseMessage()));
5683
}
5784

5885
private void Records_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
5986
{
60-
if(_EventLogRepository != null)
61-
{
62-
LogCount = _EventLogRepository.Records.Count;
63-
}
87+
//OnPropertyChanged(nameof(LogCount));
88+
//OnPropertyChanged(nameof(LogRecords));
6489
}
6590

6691
Progress<long> _Progress;
6792
public ICommand OpenCommand { get; private set; }
93+
public ICommand CloseCommand { get; private set; }
6894
long _LogCount;
6995
public long LogCount
7096
{
71-
get => _LogCount;
72-
set
97+
get
7398
{
74-
_LogCount = value;
75-
99+
if (_EventLogRepository != null && _EventLogRepository.Records != null)
100+
{
101+
return _EventLogRepository.Records.Count;
102+
}
103+
else
104+
{
105+
return 0;
106+
}
76107
}
77108
}
78109
public ObservableCollection<LogRecord> LogRecords => _EventLogRepository.Records;
110+
public string LoadStatus { get; private set; }
79111
}
80112
public class MyRecord(string a, int b)
81113
{

src/WEventViewer/WEventViewer.csproj

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="Avalonia" Version="11.0.10" />
13-
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.10" />
14-
<PackageReference Include="Avalonia.Desktop" Version="11.0.10" />
15-
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.10" />
16-
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.10" />
12+
<PackageReference Include="Avalonia" Version="11.0.11" />
13+
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.11" />
14+
<PackageReference Include="Avalonia.Desktop" Version="11.0.11" />
15+
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.11" />
16+
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.11" />
1717
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
18-
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.10" />
18+
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.11" />
1919
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
2020
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
21+
<PackageReference Include="R3Extensions.Avalonia" Version="1.1.13" />
2122
<PackageReference Include="System.Diagnostics.EventLog" Version="8.0.0" />
2223
</ItemGroup>
2324
</Project>

0 commit comments

Comments
 (0)