如何使后台工作线程之间的事件在它们自己的上下文中执行
How to make events between backgroundworker threads execute in their own context
这个问题是 11 年前提出的,但答案都是假定的 Winform/WPF。我想再问一遍,但要澄清这是两个后台线程。
我想要两个线程。我们称他们为:
- 线程 A(Thread.CurrentThread.ManagedThreadId 为 16)
- 线程 B(Thread.CurrentThread.ManagedThreadId 为 18);
线程 A 触发一个事件,线程 B 监听这个事件。当执行线程 B 事件侦听器(委托)时,它与线程 A 的上下文一起执行 (16)。
我想要做的是能够在线程 A (16) 中触发事件并且委托代码在线程 B (18) 的上下文中执行。
据我所知,在这种情况下没有可用的 SynchronizationContext。
我该怎么做?
感谢您的帮助。
您可以考虑使用 Microsoft 的 Reactive Framework(又名 Rx)- NuGet System.Reactive
并添加 using System.Reactive.Linq;
- 这样您就可以利用 EventLoopScheduler
class。 class 创建了一个线程,您可以通过多种方式安排任务。
给定 private EventLoopScheduler _eventLoopScheduler = new EventLoopScheduler();
我可以对特定线程上的 运行 代码执行此操作:
IDisposable scheduled =
_eventLoopScheduler
.Schedule(() =>
{
/* Run code in the `EventLoopScheduler` */
});
您甚至可以安排将来的活动并使它们重复发生。要取消预定代码,您可以调用 scheduled.Dispose()
.
现在,给定 private event EventHandler MyEvent;
我可以使用 Rx 库执行此操作:
IDisposable subscription =
Observable
.FromEventPattern<EventHandler, EventArgs>(
h => this.MyEvent += h,
h => this.MyEvent -= h)
.ObserveOn(_eventLoopScheduler)
.Subscribe(x =>
{
/* Run code in the `EventLoopScheduler` */
});
这会订阅事件并将执行推送到 EventLoopScheduler
创建的线程。
完成后调用 subscription.Dispose()
和 _eventLoopScheduler.Dispose()
进行清理并让线程结束。
像往常一样,当我找到一个问题的优雅解决方案时,我会看着它并想知道为什么它不以这种方式从我的脑海中倾泻而出?遗憾的是,我花了很长时间才到达那里,但我对结果以及如何不费吹灰之力就可以重复使用感到满意。
我希望这是一本有用且有趣的读物:
https://codinglifestyle.wordpress.com/2021/04/15/thread-synchronization-between-worker-threads/
干杯,
克里斯
这个问题是 11 年前提出的,但答案都是假定的 Winform/WPF。我想再问一遍,但要澄清这是两个后台线程。
我想要两个线程。我们称他们为:
- 线程 A(Thread.CurrentThread.ManagedThreadId 为 16)
- 线程 B(Thread.CurrentThread.ManagedThreadId 为 18);
线程 A 触发一个事件,线程 B 监听这个事件。当执行线程 B 事件侦听器(委托)时,它与线程 A 的上下文一起执行 (16)。
我想要做的是能够在线程 A (16) 中触发事件并且委托代码在线程 B (18) 的上下文中执行。
据我所知,在这种情况下没有可用的 SynchronizationContext。
我该怎么做?
感谢您的帮助。
您可以考虑使用 Microsoft 的 Reactive Framework(又名 Rx)- NuGet System.Reactive
并添加 using System.Reactive.Linq;
- 这样您就可以利用 EventLoopScheduler
class。 class 创建了一个线程,您可以通过多种方式安排任务。
给定 private EventLoopScheduler _eventLoopScheduler = new EventLoopScheduler();
我可以对特定线程上的 运行 代码执行此操作:
IDisposable scheduled =
_eventLoopScheduler
.Schedule(() =>
{
/* Run code in the `EventLoopScheduler` */
});
您甚至可以安排将来的活动并使它们重复发生。要取消预定代码,您可以调用 scheduled.Dispose()
.
现在,给定 private event EventHandler MyEvent;
我可以使用 Rx 库执行此操作:
IDisposable subscription =
Observable
.FromEventPattern<EventHandler, EventArgs>(
h => this.MyEvent += h,
h => this.MyEvent -= h)
.ObserveOn(_eventLoopScheduler)
.Subscribe(x =>
{
/* Run code in the `EventLoopScheduler` */
});
这会订阅事件并将执行推送到 EventLoopScheduler
创建的线程。
完成后调用 subscription.Dispose()
和 _eventLoopScheduler.Dispose()
进行清理并让线程结束。
像往常一样,当我找到一个问题的优雅解决方案时,我会看着它并想知道为什么它不以这种方式从我的脑海中倾泻而出?遗憾的是,我花了很长时间才到达那里,但我对结果以及如何不费吹灰之力就可以重复使用感到满意。
我希望这是一本有用且有趣的读物:
https://codinglifestyle.wordpress.com/2021/04/15/thread-synchronization-between-worker-threads/
干杯, 克里斯