Blazor Server项目如何实现每秒自动刷新页面倒计时动态数据
在Blazor Server中可以通过.NET内置的定时器类实现每秒刷新倒计时,推荐使用.NET 6+ 提供的PeriodicTimer,也可以用传统的System.Threading.Timer,完整实现步骤如下:
步骤1:修改Razor展示代码
把倒计时列的占位符替换为动态计算的方法调用即可,你可以自行封装剩余时间的计算逻辑:
<Virtualize Items="@rooms" Context="room"> <table border="1"> <tr @key=room.Id> <td>@room.Id</td> <td>@room.name</td> <td>@GetCountdownText(room.closing_date)</td> </tr> </table> </Virtualize>
注意:你定义的Room实体属性
name为小写,原有代码里的@room.Name会触发属性不存在的报错,需要和实体定义的属性名保持一致。
步骤2:添加定时器与页面刷新逻辑
在页面的@code代码块中添加定时器声明、启动逻辑、计时刷新逻辑,同时实现IDisposable接口释放定时器避免内存泄漏:
@implements IDisposable @code { private List<Room> rooms = new(); private PeriodicTimer? _timer; private bool _isDisposed; protected override async Task OnInitializedAsync() { // 你自己的从数据库加载rooms数据的原有逻辑 rooms = await YourDbContext.Rooms.ToListAsync(); // 初始化每秒触发一次的定时器 _timer = new PeriodicTimer(TimeSpan.FromSeconds(1)); // 启动后台计时任务 _ = RunTimerAsync(); } private async Task RunTimerAsync() { try { // 定时器每次触发就通知UI刷新 while (await _timer!.WaitForNextTickAsync() && !_isDisposed) { // InvokeAsync确保在Blazor UI线程上执行状态更新 await InvokeAsync(StateHasChanged); } } catch (OperationCanceledException) { // 忽略定时器主动取消触发的异常 } } // 倒计时计算逻辑,你也可以用自己已经实现的计算方法替换 private string GetCountdownText(DateTime closingDate) { var remainingTime = closingDate - DateTime.Now; if (remainingTime.TotalSeconds <= 0) { return "已关闭"; } return $"Closing in {remainingTime.Minutes} minutes and {remainingTime.Seconds} seconds"; } // 组件销毁时释放定时器资源 public void Dispose() { _isDisposed = true; _timer?.Dispose(); } }
额外优化注意点
- 建议
closing_date统一使用UTC时间存储和计算,避免服务器时区和业务时区不一致导致倒计时计算错误 - 不需要为每个Room单独创建定时器,全局1个每秒刷新的定时器就可以满足所有倒计时的更新需求,避免不必要的性能损耗
- 如果需要定时同步数据库最新的房间关闭时间,可以在
RunTimerAsync的循环中添加定时重新加载rooms数据的逻辑
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

