.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
相关产品推荐
相关产品推荐

