Skip to content

Commit 778b736

Browse files
authored
Fix WebConsoleControl load/close disposal race
1 parent a3c4a4a commit 778b736

1 file changed

Lines changed: 35 additions & 12 deletions

File tree

Source/NETworkManager/Controls/WebConsoleControl.xaml.cs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using NETworkManager.Settings;
55
using NETworkManager.Utilities;
66
using System;
7+
using System.Threading;
78
using System.Windows;
89
using System.Windows.Input;
910

@@ -17,6 +18,7 @@ public partial class WebConsoleControl : UserControlBase, IDragablzTabItem
1718

1819
private bool _initialized;
1920
private bool _closed;
21+
private readonly CancellationTokenSource _loadCancellationTokenSource = new();
2022

2123
private readonly Guid _tabId;
2224
private readonly WebConsoleSessionInfo _sessionInfo;
@@ -92,25 +94,44 @@ private void Browser2_SourceChanged(object sender, CoreWebView2SourceChangedEven
9294
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
9395
{
9496
// Connect after the control is drawn and only on the first init
95-
if (_initialized)
97+
if (_initialized || _closed || _loadCancellationTokenSource.IsCancellationRequested)
9698
return;
9799

98-
// Set user data folder - Fix #382
99-
var webView2Environment =
100-
await CoreWebView2Environment.CreateAsync(null, GlobalStaticConfiguration.WebConsole_Cache);
100+
try
101+
{
102+
// Set user data folder - Fix #382
103+
var webView2Environment =
104+
await CoreWebView2Environment.CreateAsync(null, GlobalStaticConfiguration.WebConsole_Cache);
105+
106+
if (_closed || _loadCancellationTokenSource.IsCancellationRequested)
107+
return;
101108

102-
await Browser.EnsureCoreWebView2Async(webView2Environment);
109+
await Browser.EnsureCoreWebView2Async(webView2Environment);
110+
111+
if (_closed || _loadCancellationTokenSource.IsCancellationRequested || Browser.CoreWebView2 == null)
112+
return;
103113

104-
Log.Debug($"UserControl_Loaded - WebView2 profile path: {Browser.CoreWebView2.Profile.ProfilePath}");
114+
Log.Debug($"UserControl_Loaded - WebView2 profile path: {Browser.CoreWebView2.Profile.ProfilePath}");
105115

106-
// Set the default settings
107-
Browser.CoreWebView2.Settings.IsStatusBarEnabled = SettingsManager.Current.WebConsole_IsStatusBarEnabled;
108-
Browser.CoreWebView2.Settings.IsPasswordAutosaveEnabled =
109-
SettingsManager.Current.WebConsole_IsPasswordSaveEnabled;
116+
// Set the default settings
117+
Browser.CoreWebView2.Settings.IsStatusBarEnabled = SettingsManager.Current.WebConsole_IsStatusBarEnabled;
118+
Browser.CoreWebView2.Settings.IsPasswordAutosaveEnabled =
119+
SettingsManager.Current.WebConsole_IsPasswordSaveEnabled;
110120

111-
Navigate(_sessionInfo.Url);
121+
Navigate(_sessionInfo.Url);
112122

113-
_initialized = true;
123+
_initialized = true;
124+
}
125+
catch (ObjectDisposedException)
126+
{
127+
if (!_closed && !_loadCancellationTokenSource.IsCancellationRequested)
128+
throw;
129+
}
130+
catch (InvalidOperationException)
131+
{
132+
if (!_closed && !_loadCancellationTokenSource.IsCancellationRequested)
133+
throw;
134+
}
114135
}
115136

116137
#endregion
@@ -198,6 +219,8 @@ public void CloseTab()
198219
return;
199220

200221
_closed = true;
222+
_loadCancellationTokenSource.Cancel();
223+
_loadCancellationTokenSource.Dispose();
201224

202225
// Release the subscriptions that would otherwise keep this transient per-tab
203226
// control (and its heavyweight WebView2 instance) alive for the lifetime of the

0 commit comments

Comments
 (0)