两种不同类型的分配事件的事件处理程序之间的差异 [英] Difference between two different types of assigning events to event handlers
问题描述
我所以这是嘴上说的做法是不好的,另一种是好看到这个示例代码。但我不明白为什么?
作为事实上我得到那个著名的RCW COM对象错误,该职位在说这可能是一个原因。
I saw this sample code in SO that was saying one practice is bad and the other one is good. But I don't understand why? As a matter of fact I am getting that famous RCW COM object error and that post was saying this could be a reason.
public class SomeClass
{
private Interop.ComObjectWrapper comObject;
private event ComEventHandler comEventHandler;
public SomeClass()
{
comObject = new Interop.ComObjectWrapper();
// NO - BAD!
comObject.SomeEvent += new ComEventHandler(EventCallback);
// YES - GOOD!
comEventHandler = new ComEventHandler(EventCallback);
comObject.SomeEvent += comEventHandler
}
public void EventCallback()
{
// DO WORK
}
}
编辑:这里是链接到源:已 COM对象从它的基础RCW分开,不能使用
here is the link to the source: COM object that has been separated from its underlying RCW cannot be used
推荐答案
我觉得这两个代码片段是相同的,我们不'所有没带这里强/弱引用的任何问题。
I think those two code snippets are the same and we don't have any issues with strong/weak references here.
首先,如果我们的 Interop.ComObjectWrapper
提供CLR事件(存储事件处理程序委托即事件),我们一定会得到了来自 ComObjectWrapper
。我们的目标
First of all, if our Interop.ComObjectWrapper
provides CLR event (i.e. event that stores event handlers in delegates) we'll definitely got a strong reference from ComObjectWrapper
to our object.
任何代表包含两部分:目标
类型对象
和方法指针到特定的方法。如果目标
是空
比回调指向静态方法。
Any delegate contains two parts: Target
of type object
and Method Pointer to the particular method. If Target
is null
than callback points to the static method.
它不可能与类型的目标
的 WeakReference的。还有就是所谓的弱事件模式但它实现了对<顶级HREF =http://msdn.microsoft.com/en-us/library/hh199438.aspx相对=nofollow> eventmanager进行的,而不是简单的代表。
Its impossible to have a delegate with Target
of type WeakReference. There is so called Weak Event Pattern but it implements on top of EventManager instead of plain delegates.
内部事件的实施意味着,订阅事件后:
Internal event implementation means that after subscribing to the event:
comObject.SomeEvent += EventCallback;
comObject
对象隐含持有强引用在 SomeClass的
对象。 这真的不管什么样的订阅您正在使用的技术的并ComObject是否是一个COM对象包装或没有。
comObject
object implicitely holds an strong reference to the SomeClass
object. And this true regardless of what kind of subscribing technique your are using and whether ComObject is a COM object wrapper or not.
订阅事件在增加了一生来讲两个物体之间隐含的依赖。这就是为什么在.NET世界上最常见的内存泄漏引起的订阅长寿命对象的事件。 活动的用户不会死的,直到在应用程序访问的事件持有者。
Subscribing to the event adds implicit dependency between two objects in terms of lifetime. That's why the most common memory leak in .NET world caused by subscribing to events of the long-lived objects. Event subscriber will not die till event holder accessible in the application.
但事件,如果我的假设是不正确的, ComObjectWrapper
提供弱事件模式的一些概念,节省事件在现场处理程序不会帮助任何方式
But event if my assumption is not true and ComObjectWrapper
provides some notion of Weak Event Pattern, saving event handler in the field will not help any way.
让我们回顾一下事件的关键字的含义:
Lets recap what event keyword mean:
private event ComEventHandler comEventHandler;
...
comEventHandler = new ComEventHandler(EventCallback);
保存回调在当前场(基本上我们可以把私人活动作为一个简单的委托域)将不更改现有的行为。
Saving callback in current field (and basically we can treat private events as a simple delegate fields) will not change existing behavior.
我们已经知道该委托是一个简单的对象存储参考目标对象(即 SomeClass的
)对象和一个方法(即公共无效EventCallBack()
)。这意味着,在现场存放额外的代表增加了额外的参考 SomeClass的
从 SomeClass的
本身。
We already know that delegate is a simple object that stores reference to the Target object (i.e. SomeClass
object) and a method (i.e. public void EventCallBack()
). This means that storing additional delegate in field adds additional reference to the SomeClass
from the SomeClass
itself.
基本上,存储事件处理领域语义上等同于SomeClass的存储附加参考:
Basically, storing event handler in the field semantically equivalent to storing additional reference in SomeClass:
私人SomeClass的SomeClass的;
private SomeClass someClass;
公共SomeClaas()
{
//这是基本相同的comEventHandler字段$ b $存储代表
// b SomeClass的=这个;
}
public SomeClaas() { // This is basically the same as storing delegate // in the comEventHandler field someClass = this; }
保存在强引用 SomeClass的
不会延长当前对象的生命周期这意味着,如果 ComObjectWrapper
不会抱持着强烈的参考 SomeClass的
对象存储事件处理程序在 comEventHandler
不会延长SomeClass的一生并不会阻止 SomeClass的
从垃圾收集。
Storing strong reference in the SomeClass
will not prolong lifetime of the current object. And this means that if ComObjectWrapper
will not hold a strong reference to the SomeClass
object storing event handler in the comEventHandler
will not prolong SomeClass's lifetime and will not prevent SomeClass
from garbage collection.
在私有字段中存储的事件处理程序将不会延长对象的生命周期并不会阻止它的垃圾收集反正。
Storing event handler in the private field will not prolong object's lifetime and will not prevent it from garbage collection anyway.
这就是为什么有在对象的生命周期而言下面的代码片段没有什么区别:
That's why there is no difference between following code snippets in terms of object lifetime:
// GOOD!
comObject.SomeEvent += new ComEventHandler(EventCallback);
// EVEN BETTER!
comObject.SomeEvent += EventCallback;
// NOT GOOD, BECAUSE WAN'T HELP!
comEventHandler = new ComEventHandler(EventCallback);
comObject.SomeEvent += comEventHandler
这篇关于两种不同类型的分配事件的事件处理程序之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!