diff --git a/src/Uno.Extensions.Core/IDispatcher.cs b/src/Uno.Extensions.Core/IDispatcher.cs index c174969c03..02f18592f2 100644 --- a/src/Uno.Extensions.Core/IDispatcher.cs +++ b/src/Uno.Extensions.Core/IDispatcher.cs @@ -10,4 +10,9 @@ public interface IDispatcher /// An cancellation token to cancel the async operation. /// A ValueTask to asynchronously get the result of the operation. ValueTask ExecuteAsync(AsyncFunc func, CancellationToken cancellation); + + /// + /// Gets a value that specifies whether the current execution context is on the UI thread. + /// + bool HasThreadAccess { get; } } diff --git a/src/Uno.Extensions.Navigation.UI/Dispatcher.cs b/src/Uno.Extensions.Navigation.UI/Dispatcher.cs index ac29d551d1..bfd02450db 100644 --- a/src/Uno.Extensions.Navigation.UI/Dispatcher.cs +++ b/src/Uno.Extensions.Navigation.UI/Dispatcher.cs @@ -33,5 +33,14 @@ public Dispatcher(FrameworkElement element) /// public async ValueTask ExecuteAsync(AsyncFunc func, CancellationToken cancellation) - => await _dispatcher.ExecuteAsync(func, cancellation); + { + if (HasThreadAccess) + { + return await func(cancellation); + } + return await _dispatcher.ExecuteAsync(func, cancellation); + } + + /// + public bool HasThreadAccess => _dispatcher.HasThreadAccess; } diff --git a/src/Uno.Extensions.Navigation.UI/Navigator.cs b/src/Uno.Extensions.Navigation.UI/Navigator.cs index a81ef9e011..30a23bab57 100644 --- a/src/Uno.Extensions.Navigation.UI/Navigator.cs +++ b/src/Uno.Extensions.Navigation.UI/Navigator.cs @@ -45,11 +45,17 @@ protected Navigator( var regionUpdateId = RouteUpdater?.StartNavigation(Region) ?? Guid.Empty; try { + + if (Dispatcher.HasThreadAccess) + { + if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformationMessage($"Navigation started on UI thread, so moving to background thread"); + return await Task.Run(() => NavigateAsync(request)); + } + if (request.Source is null) { if (Logger.IsEnabled(LogLevel.Information)) Logger.LogInformationMessage($"Starting Navigation - Navigator: {this.GetType().Name} Request: {request.Route}"); request = request with { Source = this }; - return await Task.Run(() => NavigateAsync(request)); } diff --git a/src/Uno.Extensions.Navigation/NavigationRequest.cs b/src/Uno.Extensions.Navigation/NavigationRequest.cs index ace7967a9c..068de8814f 100644 --- a/src/Uno.Extensions.Navigation/NavigationRequest.cs +++ b/src/Uno.Extensions.Navigation/NavigationRequest.cs @@ -1,11 +1,9 @@ namespace Uno.Extensions.Navigation; #pragma warning disable SA1313 // Parameter names should begin with lower-case letter -public record NavigationRequest(object Sender, Route Route, CancellationToken? Cancellation = default, Type? Result = null) +public record NavigationRequest(object Sender, Route Route, CancellationToken? Cancellation = default, Type? Result = null, INavigator? Source = null) #pragma warning restore SA1313 // Parameter names should begin with lower-case letter { - internal INavigator? Source { get; init; } - public override string ToString() => $"Request [Sender: {Sender.GetType().Name}, Route:{Route}, Result: {Result?.Name ?? "N/A"}]"; internal virtual IResponseNavigator? GetResponseNavigator(IResponseNavigatorFactory responseFactory, INavigator navigator) => default; diff --git a/testing/TestHarness/TestHarness.UITest/Constants.cs b/testing/TestHarness/TestHarness.UITest/Constants.cs index db7bc9d198..2443c49665 100644 --- a/testing/TestHarness/TestHarness.UITest/Constants.cs +++ b/testing/TestHarness/TestHarness.UITest/Constants.cs @@ -4,7 +4,7 @@ namespace TestHarness.UITest; public class Constants { - public readonly static string WebAssemblyDefaultUri = "https://localhost:51571"; + public readonly static string WebAssemblyDefaultUri = "https://localhost:64052"; public readonly static string iOSAppName = "uno.platform.extensions.demo"; public readonly static string AndroidAppName = "uno.platform.extensions.demo"; public readonly static string iOSDeviceNameOrId = "iPad Pro (12.9-inch) (4th generation)";