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

.NET 8 Blazor主布局OnAfterRenderAsync生命周期未触发求助

Blazor静态渲染布局中实现自动登出的问题与解决方案尝试

问题背景

我是.NET Blazor新手,正在开发Web应用的自动登出功能:页面加载时启动计时器,检测到客户端交互就重置计时器。原本打算把这个功能嵌入主布局(推测为静态渲染模式),但发现OnAfterRenderAsync(bool firstRender)生命周期事件完全不触发——查了下这个事件仅对交互式组件生效。

当前核心问题:页面未完全渲染时无法访问JSRuntime,使用Task.Wait()属于不良实践,其他生命周期事件又会因渲染状态报错。

已找到的参考方向

已找到官方相关文档内容,待测试。

现有代码

MainLayout.razor

public partial class MainLayout : IDisposable
{
    private System.Timers.Timer? _timeoutTimer;

    [Inject]
    private IIdentityService? IdentityService { get; set; }

    [Inject]
    private IJSRuntime? JSRuntime { get; set; }


    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // 设置计时器为1分钟(注释标注为5分钟)
            _timeoutTimer = new System.Timers.Timer((int)(1 * 60 * 1000));
            _timeoutTimer.Elapsed += TimeoutTimerElapsed;
            _timeoutTimer.AutoReset = false;

            await JSRuntime!.InvokeVoidAsync("timeOutCall", DotNetObjectReference.Create(this));
        }
    }

    [JSInvokable]
    public void TimerInterval()
    {
        if (_timeoutTimer is null)
            ArgumentNullException.ThrowIfNull(_timeoutTimer, nameof(_timeoutTimer));

        // 用户活跃时重置计时器并重启
        _timeoutTimer.Stop();
        _timeoutTimer.Start();
    }

    private void TimeoutTimerElapsed(object? sender, ElapsedEventArgs e)
    {
        InvokeAsync(async () => await IdentityService!.LogoutAsync());
    }

    public void Dispose()
    {
        if (_timeoutTimer is not null)
            _timeoutTimer.Dispose();
    }
}

auth.js

function timeOutCall(dotnethelper) {
    var eventTypes = ['click', 'mousemove', 'keypress', 'scroll', 'touchstart', 'touchmove'];
    var timer;

    function resetTimeDelay() {
        clearTimeout(timer);
        timer = setTimeout(function () { dotnethelper.invokeMethodAsync("TimerInterval"); }, 1000); // 无活动1秒后重置计时器
    }

    eventTypes.forEach(function (eventType) {
        document.addEventListener(eventType, resetTimeDelay);
    });

    // 组件卸载或计时器重置时移除事件监听器
    function removeListeners() {
        eventTypes.forEach(function (eventType) {
            document.removeEventListener(eventType, resetTimeDelay);
        });
    }

    // 返回移除监听器的函数
    return removeListeners;
}

内容的提问来源于stack exchange,提问作者B.Spangenberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:23:17