【问题标题】:Handling an event on the subscriber thread - C#处理订阅者线程上的事件 - C#
【发布时间】:2011-04-03 19:00:14
【问题描述】:

一直在对多线程 C# 事件处理进行一些简短的研究,因为我怀疑事件处理程序只会在调用事件的任何线程上被调用,事实证明这是真的。

现在这让我觉得这是一个非常糟糕的主意,因为订阅对象上的事件的代码可能根本不是设计为多线程的,并且该对象的实现(应该是一个黑盒子,不是吗? ),如果幕后的多线程(如我的情况)会导致订阅者代码在多个线程上执行,从而导致各种奇怪的问题。

所以我的问题是,是否可以将事件推送回最初订阅它的线程,从而避免订阅者级别的任何意外并发?或者更抽象地说,我是否可以在某个时间点记录当前线程,并在稍后的某个时间点将事件处理程序调用(或任意一段代码)推送到该线程上?

关键是:我在不引用 WinForms 或 WPF 的 DLL 中执行此操作。我知道这些框架中存在允许这样做的构造(我自己也使用过它们),但我想这样做而不必引用这些库。

一点背景:

我的设计使用后台线程来处理一个对象,这可能会导致其属性发生变化。我使用 INotifyPropertyChanged 向观察者表明对这些属性的更改。我在库外部使用 WPF 在接口中显示这些对象,因此 INotifyPropertyChanged 很有用,因为它告诉 WPF 在正在显示的对象上的属性发生更改时更新屏幕。

我假设 WPF 在内部处理多线程更改通知,所以如果我只坚持 WPF,可能不会有问题。但是,我希望任何人都能够订阅更改事件,而不必担心它们会在后台线程上被调用。

【问题讨论】:

  • 您遇到了更大的问题,您正在更新工作线程中的属性,这些属性也可能(可能会)在 UI 线程中使用。您还需要确保 UI 线程以线程安全的方式使用它们。
  • 在后台线程中设置的属性只会被其他线程读取,所以这应该不是问题。
  • 呃,如果 UI 线程不读取这些属性,那么生成事件的意义何在? “仅由其他线程读取”问题,您不能在没有同步的情况下在一个线程上写入并在其他线程上读取。
  • “其他线程”是指除了写作线程之外的其他线程——即包括 UI 线程。我认为在其他线程上阅读没有问题,至少没有考虑到设计的其余部分。主要从 INotifyPropertyChanged 的​​角度来考虑它——我们只需要在属性更改时通知观察者,以便它可以更新内容。不完全同步也没关系,只要每次更改后都有一个 PropertyChanged 事件。

标签: c# .net multithreading events


【解决方案1】:

您可以使用SynchronizationContext 类在 UI 线程上运行代码,而无需引用 WinForms 或 WPF。

在添加处理程序时捕获SyncronizationContext.Current,然后使用捕获的实例调用每个处理程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多