Skip to content

Commit acbb2e9

Browse files
Gadflylove-linger
authored andcommitted
fix: handle canceled command log updates during shutdown
Catch TaskCanceledException from synchronous log dispatch when the application exits. Use a UI dispatcher timer for log duration updates to avoid background callbacks waiting on a closing dispatcher.
1 parent a396ed0 commit acbb2e9

2 files changed

Lines changed: 28 additions & 13 deletions

File tree

‎src/ViewModels/CommandLog.cs‎

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Text;
4+
using System.Threading.Tasks;
45
using Avalonia.Threading;
56
using CommunityToolkit.Mvvm.ComponentModel;
67

@@ -58,7 +59,14 @@ public void AppendLine(string line = null)
5859
{
5960
if (!Dispatcher.UIThread.CheckAccess())
6061
{
61-
Dispatcher.UIThread.Invoke(() => AppendLine(line));
62+
try
63+
{
64+
Dispatcher.UIThread.Invoke(() => AppendLine(line));
65+
}
66+
catch (TaskCanceledException)
67+
{
68+
// Pending UI updates are canceled when the application exits.
69+
}
6270
}
6371
else
6472
{
@@ -77,7 +85,15 @@ public void Complete()
7785
{
7886
if (!Dispatcher.UIThread.CheckAccess())
7987
{
80-
Dispatcher.UIThread.Invoke(Complete);
88+
try
89+
{
90+
Dispatcher.UIThread.Invoke(Complete);
91+
}
92+
catch (TaskCanceledException)
93+
{
94+
// Pending UI updates are canceled when the application exits.
95+
}
96+
8197
return;
8298
}
8399

‎src/Views/CommandLogTime.cs‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Threading;
32

43
using Avalonia.Controls;
54
using Avalonia.Interactivity;
@@ -35,22 +34,22 @@ private void SetupCommandLog(ViewModels.CommandLog log)
3534
if (log.IsComplete)
3635
return;
3736

38-
_refreshTimer = new Timer(_ =>
37+
_refreshTimer = new DispatcherTimer();
38+
_refreshTimer.Interval = TimeSpan.FromMilliseconds(100);
39+
_refreshTimer.Tick += (_, _) =>
3940
{
40-
Dispatcher.UIThread.Invoke(() =>
41-
{
42-
Text = GetDisplayText(log);
43-
if (log.IsComplete)
44-
StopTimer();
45-
});
46-
}, null, 0, 100);
41+
Text = GetDisplayText(log);
42+
if (log.IsComplete)
43+
StopTimer();
44+
};
45+
_refreshTimer.Start();
4746
}
4847

4948
private void StopTimer()
5049
{
5150
if (_refreshTimer is not null)
5251
{
53-
_refreshTimer.Dispose();
52+
_refreshTimer.Stop();
5453
_refreshTimer = null;
5554
}
5655
}
@@ -69,6 +68,6 @@ private static string GetDisplayText(ViewModels.CommandLog log)
6968
return $"{duration.TotalMilliseconds:G3} ms";
7069
}
7170

72-
private Timer _refreshTimer = null;
71+
private DispatcherTimer _refreshTimer = null;
7372
}
7473
}

0 commit comments

Comments
 (0)