简体   繁体   English

提出活动的假设

[英]Assumptions on event raising

Imagine the following class: 想象一下以下课程:

class A
{
     public event EventHandler AnyEvent;
}

You create an instance of class A , and attach some event handlers. 您创建类A的实例,并附加一些事件处理程序。 Now if AnyEvent gets raised, I would not assume, that the event handlers are performed on another thread, than the thread I created the object. 现在,如果AnyEvent ,则我不认为事件处理程序将在我创建对象的线程之外的另一个线程上执行。 This would be of prime importance, if you created the object on a GUI thread, and the event handler performs operations on GUI elements. 如果您在GUI线程上创建了对象,并且事件处理程序对GUI元素执行了操作,那么这将是最重要的。 This would force me to use appropriate invocation patterns. 这将迫使我使用适当的调用模式。

It really becomes evil, if you use interfaces defining events: 如果使用定义事件的接口,这真的变得邪恶:

interface B
{
     event EventHandler SomeEvent;
}

Now one implementation could raise the event from the original thread, the next from a second thread. 现在,一个实现可以从原始线程引发事件,而另一个从另一个线程引发事件。 This can cause your application to successfully work with the one, and fail with the other implementation. 这可能会导致您的应用程序成功使用一个应用程序,而无法使用另一个实现。

I think coding should always be transparent - this is not! 我认为编码应该始终透明-这不是! And if I don't create another thread, I do not assume, that my methods are performed from any other than my home thread. 而且,如果我不创建另一个线程,则不会假设我的方法是从本地线程以外的任何其他线程执行的。

Are there any aspects I did not consider? 有没有我没有考虑的方面? Any that would invalidate my assumption? 有什么会使我的假设无效吗?

There is no magic with events. 事件没有魔术。 Events are handled on the thread that raises them. 事件在引发事件的线程上处理。 It has nothing to do with the thread that creates the object. 它与创建对象的线程无关。

Threading is the responsibility the consumer of the class, not the writer of the class, so your assumption is incorrect. 线程是类的使用者的责任,而不是类的编写者的责任,因此您的假设是错误的。

One should assume a class is not thread-safe unless it is documented to be thread-safe. 一个人应该假设一个类不是线程安全的,除非它被证明是线程安全的。 Even most built-in .NET classes are not thread safe unless they say they are. 甚至大多数内置的.NET类都不是线程安全的,除非他们说是安全的。

It is up to the consumer of the class to be aware of threading. 由类的使用者来了解线程。

Calling events is just calling some method (or collection of methods) using a mechanism such as function pointers. 调用事件只是使用诸如函数指针之类的机制来调用某些方法(或方法集合)。

Events are completely oblivious to the thread that attached them, and don't have any other information that could lead to properly Invoking the methods on the right thread. 事件完全忽略了附加事件的线程,并且没有任何其他信息可以导致在正确的线程上正确调用方法。

Maybe you are drawing your assumptions from COM days? 也许您是从COM时代得出的假设?

事件的处理程序回调在引发事件的同一线程上。

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

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