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

MudBlazor表格倒计时列如何实现每分钟动态更新?

实现MudBlazor表格中倒计时列的自动每分钟更新

核心思路

通过在组件内添加定时任务,每分钟触发一次局部UI更新,只刷新Time Left列的内容,无需整页重载。同时优化计算逻辑,避免不必要的性能开销。

实现步骤及代码示例

  1. 添加定时更新逻辑
    在组件的代码块中声明定时器,初始化时启动每分钟的回调,并在组件销毁时释放资源:
<MudTable Items="@TaskItems" Hover="true" Striped="true">
    <HeaderContent>
        <MudTh>任务名称</MudTh>
        <MudTh>截止时间</MudTh>
        <MudTh>剩余时间</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd>@context.TaskName</MudTd>
        <MudTd>@context.StopTime.ToString("yyyy-MM-dd HH:mm:ss")</MudTd>
        <MudTd>@GetTimeLeft(context.StopTime)</MudTd>
    </RowTemplate>
</MudTable>

@code {
    private List<TaskItem> TaskItems { get; set; } = new();
    private Timer? _countdownTimer;

    protected override async Task OnInitializedAsync()
    {
        // 模拟从数据源加载数据
        TaskItems = await LoadTaskDataAsync();
        
        // 启动定时器:立即执行一次,之后每分钟执行
        _countdownTimer = new Timer(TriggerCountdownUpdate, null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
    }

    private void TriggerCountdownUpdate(object? state)
    {
        // 必须通过InvokeAsync切换到Blazor同步上下文,否则无法更新UI
        InvokeAsync(StateHasChanged);
    }

    private string GetTimeLeft(DateTime stopTime)
    {
        var timeDiff = stopTime - DateTime.Now;
        return timeDiff <= TimeSpan.Zero 
            ? "已到期" 
            : $"{timeDiff.Hours:D2}:{timeDiff.Minutes:D2}:{timeDiff.Seconds:D2}";
    }

    // 组件销毁时释放定时器,防止内存泄漏
    public void Dispose()
    {
        _countdownTimer?.Dispose();
    }

    // 模拟数据加载方法
    private Task<List<TaskItem>> LoadTaskDataAsync()
    {
        return Task.FromResult(new List<TaskItem>
        {
            new() { TaskName = "项目A", StopTime = DateTime.Now.AddHours(1.5) },
            new() { TaskName = "项目B", StopTime = DateTime.Now.AddMinutes(45) }
        });
    }

    public class TaskItem
    {
        public string TaskName { get; set; } = string.Empty;
        public DateTime StopTime { get; set; }
    }
}
  1. 性能优化建议
  • 如果表格数据量较大,建议在定时器回调中预先计算并更新每个条目的剩余时间字段(比如给TaskItem添加TimeLeft属性),避免每次渲染时重复计算:
    private void TriggerCountdownUpdate(object? state)
    {
        InvokeAsync(() =>
        {
            foreach (var item in TaskItems)
            {
                var timeDiff = item.StopTime - DateTime.Now;
                item.TimeLeft = timeDiff <= TimeSpan.Zero ? "已到期" : $"{timeDiff.Hours:D2}:{timeDiff.Minutes:D2}:{timeDiff.Seconds:D2}";
            }
            StateHasChanged();
        });
    }
    
    然后在表格列中直接绑定@context.TimeLeft即可。
  • 避免设置过于频繁的更新间隔,每分钟更新足以满足需求,减少UI渲染压力。
  1. 关键注意事项
  • 定时器回调运行在后台线程,必须使用InvokeAsync将UI更新操作切换到Blazor的同步上下文,否则会引发线程异常。
  • 务必在组件销毁时释放定时器(实现IDisposable接口),防止内存泄漏。

内容的提问来源于stack exchange,提问作者Tom Gordon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:17:13