Skip to content

Commit 5507fb9

Browse files
authored
Merge pull request #20622 from unoplatform/mergify/bp/release/stable/6.0/pr-20618
fix: Fix multiple instance of dev-server can be started when re-using VS sinatnce with multiple solutions (backport #20618)
2 parents 2eb8d74 + 35fceb3 commit 5507fb9

File tree

2 files changed

+55
-29
lines changed

2 files changed

+55
-29
lines changed

src/Uno.UI.RemoteControl.VS/DebuggerHelper/ProfilesObserver.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,26 @@ private void ObserveSolutionEvents()
218218
_dte.Events.CommandEvents.AfterExecute += _afterExecute;
219219
}
220220

221+
private void UnObserveSolutionEvents()
222+
{
223+
if (_projectAdded is not null)
224+
{
225+
_dte.Events.SolutionEvents.ProjectAdded -= _projectAdded;
226+
}
227+
if (_projectRemoved is not null)
228+
{
229+
_dte.Events.SolutionEvents.ProjectRemoved -= _projectRemoved;
230+
}
231+
if (_projectRenamed is not null)
232+
{
233+
_dte.Events.SolutionEvents.ProjectRenamed -= _projectRenamed;
234+
}
235+
if (_afterExecute is not null)
236+
{
237+
_dte.Events.CommandEvents.AfterExecute -= _afterExecute;
238+
}
239+
}
240+
221241
private async Task OnUnconfiguredProject_ProjectUnloadingAsync(object? sender, EventArgs args)
222242
{
223243
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
@@ -412,6 +432,7 @@ private void EnsureActiveDebugFrameworkServices()
412432

413433
public void Dispose()
414434
{
435+
UnObserveSolutionEvents();
415436
_projectRuleSubscriptionLink?.Dispose();
416437
_isDisposed = true;
417438
}

src/Uno.UI.RemoteControl.VS/EntryPoint.cs

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -321,47 +321,52 @@ private async Task OnStartupProjectChangedAsync()
321321

322322
private async Task EnsureServerAsync()
323323
{
324+
if (_isDisposed || _closing)
325+
{
326+
return;
327+
}
328+
324329
_debugAction?.Invoke($"Starting server (tid:{Environment.CurrentManagedThreadId})");
325330

326331
// As Android projects are "library", we cannot filter on "Application" projects.
327332
// Instead, we persist the port only in the current startup projects ... and we make sure to re-write it when the startup project changes (cf. OnStartupProjectChangedAsync).
328333
const ProjectAttribute persistenceFilter = ProjectAttribute.Startup;
329334

330-
var persistedPorts = (await _dte
331-
.GetProjectUserSettingsAsync(_asyncPackage, RemoteControlServerPortProperty, persistenceFilter))
332-
.Distinct(StringComparer.OrdinalIgnoreCase)
333-
.Select(str => int.TryParse(str, out var p) ? p : -1)
334-
.ToArray();
335-
var persistedPort = persistedPorts.FirstOrDefault(p => p > 0);
335+
await _devServerGate.WaitAsync();
336+
try
337+
{
338+
var persistedPorts = (await _dte
339+
.GetProjectUserSettingsAsync(_asyncPackage, RemoteControlServerPortProperty, persistenceFilter))
340+
.Distinct(StringComparer.OrdinalIgnoreCase)
341+
.Select(str => int.TryParse(str, out var p) ? p : -1)
342+
.ToArray();
343+
var persistedPort = persistedPorts.FirstOrDefault(p => p > 0);
336344

337-
var port = _devServer?.port ?? persistedPort;
338-
// Determine if the port configuration is incorrect:
339-
// - Either no ports or multiple ports are persisted (`persistedPorts is { Length: 0 or > 1 }`).
340-
// - Or the currently used port (`port`) does not match the persisted port (`persistedPort`).
341-
var portMisConfigured = persistedPorts is { Length: 0 or > 1 } || port != persistedPort;
345+
var port = _devServer?.port ?? persistedPort;
346+
// Determine if the port configuration is incorrect:
347+
// - Either no ports or multiple ports are persisted (`persistedPorts is { Length: 0 or > 1 }`).
348+
// - Or the currently used port (`port`) does not match the persisted port (`persistedPort`).
349+
var portMisConfigured = persistedPorts is { Length: 0 or > 1 } || port != persistedPort;
342350

343-
if (_devServer is { process.HasExited: false })
344-
{
345-
if (portMisConfigured)
351+
if (_devServer is { process.HasExited: false })
346352
{
347-
_debugAction?.Invoke($"Server already running on port {_devServer?.port}, but port is not configured properly on all projects. Updating it ...");
353+
if (portMisConfigured)
354+
{
355+
_debugAction?.Invoke($"Server already running on port {_devServer?.port}, but port is not configured properly on all projects. Updating it ...");
348356

349-
// The dev-server is already running, but at least one project is not configured properly
350-
// (This can happen when a project is being added to the solution while opened - Reminder: This EnsureServerAsync is invoked each time a project is built)
351-
// We make sure to set the current port for **all** projects.
352-
await _dte.SetProjectUserSettingsAsync(_asyncPackage, RemoteControlServerPortProperty, port.ToString(CultureInfo.InvariantCulture), persistenceFilter);
353-
}
354-
else
355-
{
356-
_debugAction?.Invoke($"Server already running on port {_devServer?.port}");
357-
}
357+
// The dev-server is already running, but at least one project is not configured properly
358+
// (This can happen when a project is being added to the solution while opened - Reminder: This EnsureServerAsync is invoked each time a project is built)
359+
// We make sure to set the current port for **all** projects.
360+
await _dte.SetProjectUserSettingsAsync(_asyncPackage, RemoteControlServerPortProperty, port.ToString(CultureInfo.InvariantCulture), persistenceFilter);
361+
}
362+
else
363+
{
364+
_debugAction?.Invoke($"Server already running on port {_devServer?.port}");
365+
}
358366

359-
return;
360-
}
367+
return;
368+
}
361369

362-
await _devServerGate.WaitAsync();
363-
try
364-
{
365370
if (EnsureTcpPort(ref port) || portMisConfigured)
366371
{
367372
// The port has changed, or all application projects does not have the same port number (or is not configured), we update port in *all* user files

0 commit comments

Comments
 (0)