UWP开发中如何通过定时器按间隔调用函数 出现委托匹配报错排查
编译报错的核心原因
System.Timers.Timer的Elapsed事件对应的委托是ElapsedEventHandler,它强制要求绑定的回调方法签名必须是void 方法名(object sender, ElapsedEventArgs e)的形式。- 你当前直接绑定的
PresencePage_Loaded方法,第二个参数的类型是RoutedEventArgs,和委托要求的ElapsedEventArgs类型完全不兼容,因此编译器判定签名不匹配,直接抛出报错。 - 额外的隐藏坑:就算通过强转等方式绕过编译,
System.Timers.Timer的Elapsed事件是在线程池工作线程上触发的,直接在回调里操作UWP的UI元素会触发跨线程访问异常,根本无法正常运行。另外你当前的代码漏写了aTimer.Start()方法,就算签名完全匹配,不调用启动方法定时器也永远不会触发。
正确实现方案
方案1:适配System.Timers.Timer的修复写法
核心逻辑是单独写一个符合ElapsedEventHandler签名的中间回调,在回调内处理跨线程切换,再调用你原本的业务方法:
// 定时器对象定义在类级别,方便后续停止、释放 private System.Timers.Timer aTimer; private void TimedEvent() { aTimer = new System.Timers.Timer(); aTimer.Interval = 40000; // 单位为毫秒,40000对应40秒间隔 aTimer.AutoReset = true; // 绑定符合签名要求的中间回调 aTimer.Elapsed += OnTimerTriggered; // 必须手动启动定时器,否则永远不会触发 aTimer.Start(); } // 完全匹配ElapsedEventHandler签名的中间回调 private async void OnTimerTriggered(object sender, ElapsedEventArgs e) { // 切回UI线程执行业务逻辑,避免跨线程访问异常 await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => { // 调用你原本需要执行的目标方法 await PresencePage_Loaded(sender, new RoutedEventArgs()); }); } private async Task PresencePage_Loaded(object sender, RoutedEventArgs e) { // 原有业务逻辑直接写在这里即可 }
方案2:UWP场景推荐的原生实现(无跨线程问题)
UWP内置了适配UI线程的DispatcherTimer,它的Tick事件直接在UI线程触发,不需要手动处理跨线程切换,代码更简洁也更稳定:
// 类级别定义定时器对象 private Windows.UI.Xaml.DispatcherTimer uiTimer; private void TimedEvent() { uiTimer = new Windows.UI.Xaml.DispatcherTimer(); // 直接设置触发间隔,40秒 uiTimer.Interval = TimeSpan.FromMilliseconds(40000); // 直接绑定业务逻辑,不需要写中间回调 uiTimer.Tick += async (s, args) => { await PresencePage_Loaded(s, new RoutedEventArgs()); }; uiTimer.Start(); }
注意事项
- 页面/组件卸载时,一定要调用定时器的
Stop()方法并释放对应资源,避免定时器持续运行造成内存泄漏。 - 如果不需要定时器重复触发,把
AutoReset属性设置为false即可,触发一次后就会自动停止。
内容的提问来源于stack exchange,提问作者Megatron213
相关产品推荐
相关产品推荐

