如何让System.Threading.Timer触发的EventHandler在原始线程执行Invoke
实现方案
核心依赖.NET内置的SynchronizationContext(同步上下文)实现线程调度,不需要依赖UI控件的Invoke方法。
通用实现(适用UI线程/带同步上下文的线程)
首先在调用Start方法时捕获当前线程的同步上下文,Timer回调中通过该上下文调度事件执行,修改后的代码如下:
public event EventHandler StatusChanged; // 存储原始线程的同步上下文 private SynchronizationContext _originalSyncContext; public void Start() { StatusChanged += new EventHandler(SomethingChangedMethod); // 捕获调用Start方法线程的同步上下文 _originalSyncContext = SynchronizationContext.Current ?? new SynchronizationContext(); new Timer(Pending, null, 0, 1000); } private void Pending(object state) { // 执行定时任务逻辑 // Do Something // 异步调度到原始线程执行事件 // 如果需要同步阻塞等待执行完成,可以替换为Send方法 _originalSyncContext.Post(_ => { StatusChanged?.Invoke(this, EventArgs.Empty); }, null); }
说明:如果调用
Start的是WPF/WinForm/MAUI等框架的UI线程,框架会自动提供对应同步上下文实现,上述代码直接生效,事件会自动切回原始UI线程执行。
自定义普通线程调度方案
如果调用Start的是你自己创建的普通工作线程(比如控制台程序的自定义线程),默认没有同步上下文,需要给原始线程添加消息循环,自定义同步上下文实现,示例如下:
1. 实现自定义同步上下文
public class CustomThreadSynchronizationContext : SynchronizationContext { private readonly BlockingCollection<(SendOrPostCallback Callback, object State)> _taskQueue = new(); // 启动当前线程的消息循环 public void RunMessageLoop() { foreach (var task in _taskQueue.GetConsumingEnumerable()) { task.Callback(task.State); } } // 停止消息循环 public void StopMessageLoop() => _taskQueue.CompleteAdding(); // 异步调度任务 public override void Post(SendOrPostCallback d, object state) { _taskQueue.Add((d, state)); } // 同步调度任务 public override void Send(SendOrPostCallback d, object state) { using var waitHandle = new ManualResetEventSlim(false); _taskQueue.Add((s => { d(s); waitHandle.Set(); }, state)); waitHandle.Wait(); } }
2. 原始线程使用方式
// 原始线程执行逻辑 // 初始化自定义同步上下文 var syncContext = new CustomThreadSynchronizationContext(); // 将上下文绑定到当前线程 SynchronizationContext.SetSynchronizationContext(syncContext); // 在这里调用你的业务类Start方法 var businessInstance = new YourBusinessClass(); businessInstance.Start(); // 启动消息循环,后续所有调度到该上下文的任务都会在当前线程执行 syncContext.RunMessageLoop();
说明:需要停止原始线程时调用
StopMessageLoop方法即可退出消息循环。
内容的提问来源于stack exchange,提问作者rkgghz
相关产品推荐
相关产品推荐

