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

如何在Xamarin Forms中实现异步版Device.StartTimer?

实现Xamarin Forms中Device.StartTimer的异步版本

你的核心问题在于Device.StartTimer的回调是同步返回bool的,无法直接等待异步操作完成,原代码里的retVal会在异步的RefreshAsync执行前就返回初始值false,导致定时器只执行一次就停止,且得不到正确结果。

解决方案:封装异步版本的定时器

我们可以自己实现异步定时器逻辑,用Task.Delay结合循环替代Device.StartTimer,这样就能在回调里安全等待异步方法的结果:

public static async Task AsyncStartTimer(TimeSpan interval, Func<Task<bool>> callback)
{
    do
    {
        // 等待定时器间隔
        await Task.Delay(interval);
        
        // 执行异步回调,获取是否继续的结果
        var shouldContinue = await callback().ConfigureAwait(false);
        
        if (!shouldContinue)
            break;
            
    } while (true);
}

替换原代码使用

把原来的Device.StartTimer调用换成这个异步方法,回调里直接处理异步逻辑:

// 启动异步定时器,无需担心同步返回的问题
_ = AsyncStartTimer(TimeSpan.FromMilliseconds(500), async () =>
{
    // 直接await你的异步方法,获取结果
    var retVal = await this.RefreshAsync().ConfigureAwait(true);
    
    // 返回是否继续执行定时器
    return retVal;
});

针对你的业务场景说明

你的RefreshAsync会等待iOS的ShowAlertAsync(Toast动画完成),现在用这个异步定时器后,每次定时器触发都会等待Toast动画完成,再根据retVal决定是否继续下一次定时,完全匹配你的需求。

原代码的问题分析

  1. Device.StartTimer的回调必须同步返回,你在里面用Device.BeginInvokeOnMainThread启动的异步委托会在稍后执行,所以retVal会立即返回初始的false,定时器直接停止。
  2. 即使你尝试在回调里等待TaskCompletionSource的任务,也会阻塞UI线程(StartTimer的回调在UI线程执行),导致界面卡死,这是必须避免的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:22:54