简体   繁体   English

如何使后台工作线程之间的事件在自己的上下文中执行

[英]How to make events between backgroundworker threads execute in their own context

This question was asked 11 years ago but the answers all assumed Winform/WPF.这个问题是 11 年前提出的,但答案都假设为 Winform/WPF。 I'd like to ask it again but clarify these are two backgroundworker threads.我想再问一次,但要澄清这是两个后台工作线程。

I'd like to have two Threads.我想要两个线程。 Let's call them:让我们称它们为:

  • Thread A (Thread.CurrentThread.ManagedThreadId is 16)线程 A(Thread.CurrentThread.ManagedThreadId 为 16)
  • Thread B (Thread.CurrentThread.ManagedThreadId is 18);线程 B(Thread.CurrentThread.ManagedThreadId 为 18);

Thread A fires an event and Thread B listens to this event.线程 A 触发一个事件,线程 B 监听这个事件。 When the Thread B event listener (delegate) is executed, it's executed with the Thread A's context (16).当执行线程 B 事件侦听器(委托)时,它与线程 A 的上下文 (16) 一起执行。

What I'd like to do is be able to fire event in Thread A (16) and the delegate code execute under the context of Thread B (18).我想做的是能够在线程 A (16) 中触发事件,并且委托代码在线程 B (18) 的上下文中执行。

From what I've seen there is no SynchronizationContext available in this scenario.从我所见,在这种情况下没有可用的 SynchronizationContext 。

How can I do that?我怎样才能做到这一点?

Thank you for your help.谢谢您的帮助。

You could consider using Microsoft's Reactive Framework (aka Rx) - NuGet System.Reactive and add using System.Reactive.Linq;您可以考虑使用 Microsoft 的反应式框架(又名 Rx) - NuGet System.Reactiveusing System.Reactive.Linq; - so that you could take advantage of the EventLoopScheduler class. - 这样您就可以利用EventLoopScheduler class。 This class creates a single thread that you can schedule tasks on in a variety of ways.此 class 创建一个线程,您可以通过多种方式安排任务。

Given private EventLoopScheduler _eventLoopScheduler = new EventLoopScheduler();给定private EventLoopScheduler _eventLoopScheduler = new EventLoopScheduler(); I can do this to run code on the specific thread:我可以这样做以在特定线程上运行代码:

IDisposable scheduled =
    _eventLoopScheduler
        .Schedule(() =>
        {
            /* Run code in the `EventLoopScheduler` */
        });

You can even schedule events in the future and make them recurring.您甚至可以安排未来的活动并使其重复发生。 To cancel scheduled code you can call scheduled.Dispose() .要取消预定代码,您可以调用scheduled.Dispose()

Now, given private event EventHandler MyEvent;现在,给定private event EventHandler MyEvent; I can do this with the Rx libraries:我可以用 Rx 库做到这一点:

IDisposable subscription =
    Observable
        .FromEventPattern<EventHandler, EventArgs>(
            h => this.MyEvent += h,
            h => this.MyEvent -= h)
        .ObserveOn(_eventLoopScheduler)
        .Subscribe(x =>
        {
            /* Run code in the `EventLoopScheduler` */
        });

This subscribes to the event and pushes execution to the thread created by the EventLoopScheduler .这订阅了事件并将执行推送到EventLoopScheduler创建的线程。

When you're done call subscription.Dispose() and _eventLoopScheduler.Dispose() to clean up and allow the thread to end.完成后,调用subscription.Dispose()_eventLoopScheduler.Dispose()进行清理并允许线程结束。

As usual when I find an elegant solution to a problem I look at it and wonder why it didn't just pour out of my head that way?像往常一样,当我找到一个问题的优雅解决方案时,我会看着它,想知道为什么它没有那样从我的脑海中倾泻而出? Sadly it took me a good while to get there but I'm happy with the result and how it could be made reusable with little effort.可悲的是,我花了很长时间才到达那里,但我对结果以及如何不费吹灰之力地使其可重复使用感到满意。

I hope it's a useful and interesting read:我希望这是一个有用和有趣的阅读:

https://codinglifestyle.wordpress.com/2021/04/15/thread-synchronization-between-worker-threads/ https://codinglifestyle.wordpress.com/2021/04/15/thread-synchronization-between-worker-threads/

Cheers, Chris干杯,克里斯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM