You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET7 MAUI加载页导航抛出Pending Navigations异常(Windows端)

.NET MAUI Windows平台"Pending Navigations still processing"导航异常解决办法

问题场景

基于.NET 7 MAUI实现登录流程,包含Dashboard页、Login页,以及作为初始路由的无布局Loading页:

  • Loading页在AppShell定义中排首位,启动时优先加载
  • 在Loading页的OnNavigatedTo方法中,根据用户本地是否保存令牌,决定重定向至Login页或Dashboard页

Android模拟器运行正常,但Windows应用抛出Pending Navigations still processing异常。临时添加await Task.Delay(1);可规避问题,但属于临时 workaround,需要更合理的解决方案。

相关代码

AppShell 标记代码:

<ShellContent
    Shell.FlyoutBehavior="Disabled"
    FlyoutItemIsVisible="False"        
    Title="Loading"
    ContentTemplate="{DataTemplate layout:LoadingPage}"
    Route="{x:Static clientApp:Routes.LoadingPage}" />

<ShellContent
    Shell.FlyoutBehavior="Disabled"
    FlyoutItemIsVisible="False"
    Title="Login"
    ContentTemplate="{DataTemplate account:LoginPage}"
    Route="{x:Static clientApp:Routes.LoginPage}" />

<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
    <ShellContent
    Title="Dashboard"
    ContentTemplate="{DataTemplate dashboard:DashboardPage}"
    Route="{x:Static clientApp:Routes.DashboardPage}" />
</FlyoutItem> 

LoadingPage 问题代码:

public partial class LoadingPage : ContentPage
{
    public LoadingPage()
    {
        InitializeComponent();        
        BindingContext = viewModel;
    }

    protected async override void OnNavigatedTo(NavigatedToEventArgs args)
    {
        base.OnNavigatedTo(args);
        // await Task.Delay(1); 取消注释可临时解决问题
        await Shell.Current.GoToAsync($"//{Routes.LoginPage}");        
    }
}

解决方案

方案1:通过Dispatcher延迟导航至UI线程空闲时机

Windows端MAUI Shell对导航时序的校验更严格,OnNavigatedTo触发时,当前页面的初始导航尚未完全完成。使用Dispatcher.DispatchAsync将导航操作排入UI队列的后续执行,避开当前pending的导航流程:

protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
    base.OnNavigatedTo(args);
    // 用Dispatcher将导航延后到当前导航完成后执行
    _ = Dispatcher.DispatchAsync(async () =>
    {
        bool hasToken = /* 你的令牌检查逻辑 */;
        string targetRoute = hasToken ? $"//{Routes.DashboardPage}" : $"//{Routes.LoginPage}";
        await Shell.Current.GoToAsync(targetRoute);
    });
}

方案2:将初始导航逻辑移至更高层级的生命周期事件

把令牌校验和导航逻辑从LoadingPage的OnNavigatedTo中移出,放到App.OnStart或Shell的Navigated事件中,确保初始导航流程完全结束后再执行跳转:

方式A:在App.xaml.cs的OnStart中处理

protected override async void OnStart()
{
    base.OnStart();
    
    bool hasToken = /* 令牌检查逻辑 */;
    string targetRoute = hasToken ? $"//{Routes.DashboardPage}" : $"//{Routes.LoginPage}";
    await Shell.Current.GoToAsync(targetRoute);
}

方式B:在AppShell的Navigated事件中处理

public AppShell()
{
    InitializeComponent();
    
    Navigated += async (sender, e) =>
    {
        // 仅当LoadingPage导航完成后执行跳转
        if (e.SourcePageType == typeof(LoadingPage))
        {
            bool hasToken = /* 令牌检查逻辑 */;
            string targetRoute = hasToken ? $"//{Routes.DashboardPage}" : $"//{Routes.LoginPage}";
            await GoToAsync(targetRoute);
        }
    };
}

方案3:禁用LoadingPage的导航缓存(配合方案1使用)

在AppShell的LoadingPage对应的ShellContent中添加NavigationCacheMode="Disabled",避免页面缓存导致的重复导航冲突:

<ShellContent
    Shell.FlyoutBehavior="Disabled"
    FlyoutItemIsVisible="False"        
    Title="Loading"
    ContentTemplate="{DataTemplate layout:LoadingPage}"
    Route="{x:Static clientApp:Routes.LoadingPage}"
    NavigationCacheMode="Disabled" />

原理说明

Windows平台MAUI Shell的导航状态管理比Android更严谨,当页面的OnNavigatedTo方法触发时,Shell内部的初始导航流程仍处于pending状态,此时直接发起新导航会触发冲突检查,抛出异常。通过Dispatcher延迟执行或移至更高层级生命周期事件,都是为了确保当前导航完全结束后再执行后续跳转,从根源上避免冲突。

内容的提问来源于stack exchange,提问作者Miloš

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:52:42