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

WinUI 3定时器回调更新TextBlock文本触发COMException异常问题

问题原因

抛出System.Runtime.InteropServices.COMException的核心原因是:System.Timers.Timer和System.Threading.Timer的回调均运行在线程池工作线程,而WinUI 3的UI控件有严格的线程亲和性限制,仅允许在创建控件的UI主线程上修改控件属性,跨线程直接操作控件就会触发该异常,这也是你更换两种线程定时器仍然报错的原因。你找到的旧方案大多面向WPF、UWP平台,WinUI 3的线程调度API有变更,直接套用自然无法生效。

修复方案

方案1:使用WinUI 3原生DispatcherTimer(优先推荐)

这是实现UI定时更新最简单的方案,DispatcherTimer是框架专为UI交互场景设计的定时器,Tick回调默认就在UI线程执行,无需额外做线程调度,直接修改控件属性即可正常运行:

public static DateTime startTime;
// 需引用Microsoft.UI.Xaml命名空间
private readonly DispatcherTimer _timer = new DispatcherTimer()
{
    Interval = TimeSpan.FromSeconds(1)
};

// 在页面/控件构造函数或者OnLoaded事件里绑定事件、启动定时器
public MainPage()
{
    InitializeComponent();
    _timer.Tick += Timer_Tick;
    _timer.Start();
}

private void Timer_Tick(object sender, object e)
{
    timerLabel.Text = DateTime.Now.Subtract(startTime).ToString(@"hh\:mm\:ss");
}

方案2:保留原有线程定时器,手动调度更新到UI线程

如果你的业务逻辑必须使用线程池定时器,可以在回调中通过DispatcherQueue把UI更新操作封送到UI线程执行:

public static DateTime startTime;
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.AutoReset = true;
timer.Elapsed += Timer_Tick;
timer.Start();

private async void Timer_Tick(object sender, EventArgs e)
{
    DispatcherQueue.TryEnqueue(() =>
    {
        timerLabel.Text = DateTime.Now.Subtract(startTime).ToString(@"hh\:mm\:ss");
    });
}

注意:WinUI 3中负责跨线程UI调度的是DispatcherQueue,而非WPF/UWP旧方案里的Dispatcher,这是多数旧教程在WinUI 3环境下失效的核心原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:36:28