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

C#中如何从System.Timer获取对象并在主线程使用及更新UI

问题原因

System.Timers.Timer的Elapsed事件在后台线程执行,而WPF的UI控件(如dataGrid_Pending)仅允许创建它的主线程(UI线程)进行访问和更新,直接在后台线程操作UI控件会导致无法更新界面,甚至引发线程安全异常。

解决方案

有两种常用的处理方式:

方式1:通过Dispatcher切回UI线程更新

在后台线程获取数据后,使用Dispatcher将UI更新操作调度回主线程执行:

private void UpdatePending(Object source, System.Timers.ElapsedEventArgs e)
{
    DataTable pending = new Repository().GetPending();

    if (pending?.Rows.Count > 0)
    {
        // 调度UI更新操作到主线程
        Application.Current.Dispatcher.Invoke(() =>
        {
            dataGrid_Pending.DataContext = pending;
        });
    }
}

同时建议调整构造函数顺序,先初始化控件再启动定时器,避免控件未初始化时触发事件:

public MainWindow()
{
    InitializeComponent();
    Timer execute = new Timer();
    execute.Interval = 5000;
    execute.Elapsed += UpdatePending;
    execute.Start();
}

方式2:使用DispatcherTimer(更适合WPF场景)

DispatcherTimer的Tick事件直接在UI线程触发,无需手动切换线程,更适合WPF的UI定时更新需求:

public MainWindow()
{
    InitializeComponent();
    DispatcherTimer execute = new DispatcherTimer();
    execute.Interval = TimeSpan.FromSeconds(5);
    execute.Tick += UpdatePending;
    execute.Start();
}

private void UpdatePending(object sender, EventArgs e)
{
    DataTable pending = new Repository().GetPending();

    if (pending?.Rows.Count > 0)
    {
        dataGrid_Pending.DataContext = pending;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:05:19