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

Blazor跳转外部站点时NavigationManager的LocationChanged事件不触发如何解决

核心结论

NavigationManager.LocationChanged 仅会在SPA站内路由跳转时触发,跳转到外部站点、刷新页面、关闭标签页等整页卸载场景本身就不会触发该事件,这是框架的正常设计。你不需要额外写JS回调,通过Blazor自带的组件生命周期机制就可以覆盖所有场景。

最优实现方案

你可以通过实现IDisposable接口配合CancellationTokenSource来完成需求,相比你现有的实现更规范,也能覆盖所有导航场景:

@inject NavigationManager navManager
@implements IDisposable

// 用取消令牌源替代手动维护的bool标识
private CancellationTokenSource _pollingCts = new();

protected override void OnInitialized()
{
    navManager.LocationChanged += OnLocationChanged;
    base.OnInitialized();
    // 启动轮询
    _ = RefreshPage();
}

private void OnLocationChanged(object sender, LocationChangedEventArgs e)
{
    // 站内导航时主动取消轮询
    _pollingCts.Cancel();
}

private async Task RefreshPage()
{
    try
    {
        while (!_pollingCts.Token.IsCancellationRequested)
        {
            await myService.GetLatestData(_pollingCts.Token);
            await InvokeAsync(StateHasChanged);
            // 取消令牌可以直接终止Task.Delay,不需要等待3秒延迟结束
            await Task.Delay(3000, _pollingCts.Token);
        }
    }
    catch (OperationCanceledException)
    {
        // 取消触发的异常属于预期行为,无需处理
    }
    finally
    {
        Console.WriteLine("Ended Data Collection.");
    }
}

// Blazor会在组件销毁、页面卸载前自动调用该方法,覆盖站内/站外导航所有场景
public void Dispose()
{
    _pollingCts.Cancel();
    _pollingCts.Dispose();
    // 取消事件订阅,避免内存泄漏
    navManager.LocationChanged -= OnLocationChanged;
}

方案说明

  • 无论是站内路由跳转,还是跳外部站点、关闭标签页等整页卸载场景,Blazor都会主动触发组件的Dispose方法,在该方法内执行取消逻辑即可覆盖所有场景
  • CancellationTokenSource是.NET下标准的异步任务取消方案,支持同时取消服务请求、延迟等待,比手动维护bool变量的响应速度更快,资源占用更低
  • 额外增加了事件订阅的取消逻辑,避免页面多次跳转后产生内存泄漏

内容的提问来源于stack exchange,提问作者Jason D

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:51:02