两种不同类型的分配事件的事件处理程序之间的差异 [英] Difference between two different types of assigning events to event handlers

查看:110
本文介绍了两种不同类型的分配事件的事件处理程序之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我所以这是嘴上说的做法是不好的,另一种是好看到这个示例代码。但我不明白为什么?
作为事实上我得到那个著名的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆