一个线程:弱引用到一个Lambda事件处理程序 [英] One Liner: WeakReference-to-a-Lambda Event Handler

查看:117
本文介绍了一个线程:弱引用到一个Lambda事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你可以看到这个一线的缺点,除了它的多次使用会违反原则?这似乎很简单,但事实上,我没有看到别人的建议,这让我想知道是否有缺点。

Can you see downsides to this one-liner other than the fact that multiple uses of it would violate the DRY principle? It seems straightforward but the fact that I haven't seen others propose it makes me wonder if there's a downside to it.

这一段代码创建了一个 WeakReference ,然后注册一个调用引用的目标的事件处理程序。

This bit of code creates a WeakReference to a method and then registers an event handler that invokes the reference's target.

SomeEvent += (sender, e) => ((Action)(new WeakReference((Action)ProcessEvent)).Target)();

谢谢,

Thanks,
Ben

推荐答案

我不认为这种模式能够满足您的期望。您是否试图阻止事件持有对当前对象的引用,以防止内存泄漏?为了评估 ProcessEvent (假设 ProcessEvent c / code>是一个实例方法),所以你仍然会有泄漏。这个代码与执行 SomeEvent + =(sender,e)=>的processEvent();

I don't think that pattern does what you expect. Are you trying to prevent the event from holding a reference to the current object so as to prevent memory leaks? The lambda expression will capture the value of this in order to evaluate ProcessEvent (assuming ProcessEvent is an instance method), so you will still have the leak. This code is the same as doing SomeEvent += (sender, e) => ProcessEvent();.

您可能会尝试更多地做这样的事情(这也不是你想要的):

You may be trying to do something more like this (which also isn't what you want):

var reference = new WeakReference((Action)ProcessEvent);
SomeEvent += (sender, e) => ((Action)reference.Target)();

现在,lambda表达式将捕获WeakReference,因此您不会对。不幸的是,没有其他的引用由ProcessEvent创建的委托,所以即使这个仍然存在,它将被删除在下一个GC上。 (这也不检查目标为null)。

Now the lambda expression will capture the WeakReference, so you won't have a strong reference to this. Unfortunately, nothing else is referencing the delegate created from ProcessEvent, so it will be removed on the next GC even if this is still alive. (This also doesn't check for Target being null).

您可以尝试以下方式:

public EventHandler MakeWeakHandler(Action action, Action<EventHandler> remove)
{
    var reference = new WeakReference(action.Target);
    var method = action.Method;
    EventHandler handler = null;
    handler = delegate(object sender, EventArgs e)
    {
        var target = reference.Target;
        if (target != null)
        {
            method.Invoke(target, null);
        }
        else
        {
            remove(handler);
        }
    };
    return handler;
}

然后使用它:

SomeEvent += MakeWeakHandler(ProcessEvent, h => SomeEvent -= h);

这将保持对ProcessEvent接收者的弱引用,并将自动从事件收集后,只要事件定期上升,应该防止内存泄漏。

That will keep a weak reference to the receiver of ProcessEvent, and will automatically remove the event handler from the event after it has been collected, which should prevent memory leaks as long as the event is raised regularly.

这篇关于一个线程:弱引用到一个Lambda事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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