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
相关产品推荐
相关产品推荐

