diff --git a/src/Uno.UI.RemoteControl.Host/RemoteControlServer.cs b/src/Uno.UI.RemoteControl.Host/RemoteControlServer.cs index dbb9d80fb160..ff91e6531b23 100644 --- a/src/Uno.UI.RemoteControl.Host/RemoteControlServer.cs +++ b/src/Uno.UI.RemoteControl.Host/RemoteControlServer.cs @@ -28,6 +28,7 @@ internal class RemoteControlServer : IRemoteControlServer, IDisposable private static readonly Dictionary _loadContexts = new(); private static readonly Dictionary _resolveAssemblyLocations = new(); private readonly Dictionary _processors = new(); + private readonly List _discoveredProcessors = new(); private readonly CancellationTokenSource _ct = new(); private WebSocket? _socket; @@ -257,7 +258,6 @@ private async Task ProcessPingFrame(Frame frame) private async Task ProcessDiscoveryFrame(Frame frame) { var assemblies = new List<(string path, System.Reflection.Assembly assembly)>(); - var discoveredProcessors = new List(); try { var msg = JsonConvert.DeserializeObject(frame.Content)!; @@ -358,12 +358,12 @@ private async Task ProcessDiscoveryFrame(Frame frame) { if (ActivatorUtilities.CreateInstance(_serviceProvider, processor.ProcessorType, parameters: new[] { this }) is IServerProcessor serverProcessor) { - discoveredProcessors.Add(new(asm.path, processor.ProcessorType.FullName!, VersionHelper.GetVersion(processor.ProcessorType), IsLoaded: true)); + _discoveredProcessors.Add(new(asm.path, processor.ProcessorType.FullName!, VersionHelper.GetVersion(processor.ProcessorType), IsLoaded: true)); RegisterProcessor(serverProcessor); } else { - discoveredProcessors.Add(new(asm.path, processor.ProcessorType.FullName!, VersionHelper.GetVersion(processor.ProcessorType), IsLoaded: false)); + _discoveredProcessors.Add(new(asm.path, processor.ProcessorType.FullName!, VersionHelper.GetVersion(processor.ProcessorType), IsLoaded: false)); if (this.Log().IsEnabled(LogLevel.Debug)) { this.Log().LogDebug("Failed to create server processor {ProcessorType}", processor.ProcessorType); @@ -372,7 +372,7 @@ private async Task ProcessDiscoveryFrame(Frame frame) } catch (Exception error) { - discoveredProcessors.Add(new(asm.path, processor.ProcessorType.FullName!, VersionHelper.GetVersion(processor.ProcessorType), IsLoaded: false, LoadError: error.ToString())); + _discoveredProcessors.Add(new(asm.path, processor.ProcessorType.FullName!, VersionHelper.GetVersion(processor.ProcessorType), IsLoaded: false, LoadError: error.ToString())); if (this.Log().IsEnabled(LogLevel.Error)) { this.Log().LogError(error, "Failed to create server processor {ProcessorType}", processor.ProcessorType); @@ -404,7 +404,7 @@ private async Task ProcessDiscoveryFrame(Frame frame) { await SendFrame(new ProcessorsDiscoveryResponse( assemblies.Select(asm => asm.path).ToImmutableList(), - discoveredProcessors.ToImmutableList())); + _discoveredProcessors.ToImmutableList())); } } diff --git a/src/Uno.UI.RemoteControl/RemoteControlClient.Status.cs b/src/Uno.UI.RemoteControl/RemoteControlClient.Status.cs index f7a9dd9543bd..047415e4a9db 100644 --- a/src/Uno.UI.RemoteControl/RemoteControlClient.Status.cs +++ b/src/Uno.UI.RemoteControl/RemoteControlClient.Status.cs @@ -150,7 +150,19 @@ public void ReportServerProcessors(ProcessorsDiscoveryResponse response) static IEnumerable GetMissingServerProcessors(ImmutableHashSet requiredProcessors, ProcessorsDiscoveryResponse response) { - var loaded = response.Processors.ToDictionary(p => p.Type, StringComparer.OrdinalIgnoreCase); + var loaded = response + .Processors + .GroupBy(p => p.Type, StringComparer.OrdinalIgnoreCase) + // If a processors is being loaded multiple times, we prefer to keep the result that has no error. + .Select(g => g + .OrderBy(p => p switch + { + { LoadError: not null } => 0, + { IsLoaded: false } => 1, + _ => 2 + }) + .Last()) + .ToDictionary(p => p.Type, StringComparer.OrdinalIgnoreCase); foreach (var required in requiredProcessors) { if (!loaded.TryGetValue(required.TypeFullName, out var actual))