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

Xamarin.Forms 如何检查System.Threading.Timer是否已被释放

Xamarin.Forms PCL项目判断System.Threading.Timer是否释放的解决方案

System.Threading.Timer 本身没有公开的已释放状态属性,你可以选择以下两种可行方案实现判断,均兼容PCL项目要求:

方案1:自定义安全计时器包装类(最推荐,无兼容性风险)

自己封装带状态标识的计时器类,完全可控,不依赖运行时内部实现:

public class SafeTimer : IDisposable
{
    private readonly Timer _innerTimer;
    private bool _isDisposed;
    private readonly object _lock = new object();

    // 构造函数和原生Timer保持一致
    public SafeTimer(TimerCallback callback, object state, int dueTime, int period)
    {
        _innerTimer = new Timer(callback, state, dueTime, period);
    }

    /// <summary>
    /// 获取计时器是否已被释放
    /// </summary>
    public bool IsDisposed
    {
        get
        {
            lock (_lock)
            {
                return _isDisposed;
            }
        }
    }

    public void Dispose()
    {
        lock (_lock)
        {
            if (_isDisposed) return;
            _innerTimer.Dispose();
            _isDisposed = true;
        }
    }

    // 按需封装原生Timer的其他方法,比如Change
    public bool Change(int dueTime, int period)
    {
        lock (_lock)
        {
            if (_isDisposed) return false;
            return _innerTimer.Change(dueTime, period);
        }
    }
}

使用时替换原有Timer声明即可:

// 原声明
// Timer _timer = new System.Threading.Timer(timerDelegate, null, period, period);
// 替换为
SafeTimer _timer = new SafeTimer(timerDelegate, null, period, period);

后续直接读取_timer.IsDisposed即可判断释放状态。

方案2:反射读取内部状态(不推荐,兼容性较差)

如果不想修改原有Timer的声明,可以通过反射读取Timer内部的私有释放标识字段,注意该方案依赖Mono运行时的内部实现,Xamarin版本更新后可能失效:

public static bool CheckTimerDisposed(Timer timer)
{
    if (timer == null) return true;
    try
    {
        var type = timer.GetType();
        // 适配不同运行时的字段名
        var field = type.GetField("disposed", BindingFlags.NonPublic | BindingFlags.Instance) 
                    ?? type.GetField("m_disposed", BindingFlags.NonPublic | BindingFlags.Instance);
        return field != null && (bool)field.GetValue(timer);
    }
    catch
    {
        // 反射失败默认返回已释放,避免后续操作抛出异常
        return true;
    }
}

不推荐的备选方案

可以尝试调用Timer的Change方法,捕获ObjectDisposedException异常来判断是否释放,该方案存在不必要的异常性能开销,仅适合临时调试使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 02:54:03