c# - 强制事件处理程序在对象的线程上运行,C# .NET

标签 c# multithreading

我有一个处理由多个成员对象创建的事件的类。来自这些对象的事件为该事件生成工作线程,以便我的类中的各种事件处理程序在不同的线程上运行(一个是串行处理程序,一个是计时器事件等)我正在寻找一种简单的方法来使我的代码线程安全,最好通过强制事件处理程序在我的对象的线程上运行。

如果这是一个 Forms UI 对象,我可以利用其 ISynchronizeInvoke 接口(interface)的实现,并调用 InvokeRequiredInvoke 等。在 WPF 中,我可以使用 Dispatcher 对象。但我的类需要*独立于任何 UI 代码运行。

这是我所拥有的一个简化示例:

public class MyClass
{
    private SomeObject object1;
    private AnotherObject object2;

    public MyClass()
    {
        object1 = new SomeObject();
        object2 = new AnotherObject();

        object1.AThreadedEvent += ThreadedEventHandler1;
        object2.AnotherThreadedEvent += ThreadedEventHandler2;
    }

    // This runs in its own thread!
    private void ThreadedEventHandler1()
    {
        // DO STUFF HERE
    }

    // This runs in its own thread!
    private void ThreadedEventHandler2()
    {
        // DO STUFF HERE
    }
}

因为两个事件处理程序都访问父类中的相同对象(包括彼此!),所以如果有一种简单的方法来强制事件处理程序在创建对象的线程中运行,那就太棒了。

我曾考虑过让我的类实现 ISynchronizeInvoke 接口(interface),但这样做似乎会变得相当复杂。在我跳入这个兔子洞之前,我想我应该联系专家看看是否有更简单的解决方案。

想法?

编辑:

我想在父对象的线程中运行事件处理程序的部分原因是因为父对象有它自己的事件,这些事件是根据其成员对象发送的事件触发的。我希望此类隐藏任何线程功能,以便使用该类的代码不必担心与线程相关的问题(即锁等)。简单地锁定共享数据并不能完成这项工作,因为我*仍然需要从线程事件处理程序中触发事件。

最佳答案

在另一个线程上调用的想法与使用 while 循环密切相关,该循环时不时地检查是否有“外部”消息需要处理。对于 UI,有一个 windows 循环可以做到这一点。对于外部线程,您必须手动编写循环。想象一下没有循环的情况,并且您有一个相对较长的运行线程,对吧?突然你想中断这个线程来调用你的消息并恢复它在同一个共享堆栈内存上正在做的事情。这种中断会破坏你的堆栈。这根本不可能。另一种可能性是使用同步机制(例如 ManualResetEvent)并等待信号(来自线程外部的信号)。因此,要恢复,为了处理来自另一个线程的消息,您基本上只有两个选择:

1)你有一个 while 循环,最终使用了一点 sleep (给其他线程一些时间/滴答声来完成他们的工作)

while (true) {
  Thread.Sleep (5);
  if (someMessageArrived) { ... }
}

2)您只需等待以某种方式实现生产者/消费者架构的消息:

On listening thread:
aManualResetEvent.WaitOne ();

On the "producer" thread:
aManualResetEvent.Set ();

.NET 框架中的高级类可能会有所帮助,例如 BlockingCollection。

希望这有帮助

关于c# - 强制事件处理程序在对象的线程上运行,C# .NET,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31732639/

相关文章:

c# - 如何从 .NET 可执行文件中获取输出并传送到 MFC 应用程序?

c# - 如何使用 Json.NET 重建我的类层次结构?

multithreading - 在哪个操作系统上线程编程足以利用多核?

java - 如何决定使用newCachedThreadPool还是newFixedThreadPool?

multithreading - futex 工具返回了意外的错误代码?

Java - 线程不想启动

c# - 如何在 wpf 数据网格中显示具有动态字段的对象?

c# - WPF 和 Silverlight 应用程序有什么区别?

c# - 以整数数组为键的字典

android - 主线程上的 Okhttp 响应回调