除了这种用法的多次使用会违反DRY原则之外,您还能看到这种不利之处吗?这似乎很简单,但是我没有见过其他人提出来的事实让我怀疑它是否有缺点。

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

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

谢谢,

最佳答案

我认为这种模式无法实现您的期望。您是否要防止事件保留对当前对象的引用,以防止内存泄漏? lambda表达式将捕获this的值以便评估ProcessEvent(假设ProcessEvent是一个实例方法),因此您仍然会泄漏。此代码与SomeEvent += (sender, e) => ProcessEvent();相同。

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

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

现在,lambda表达式将捕获WeakReference,因此您将没有对this的强烈引用。不幸的是,没有其他东西可以引用从ProcessEvent创建的委托(delegate),因此即使this仍然存在,它也会在下一个GC上被删除。 (这也不检查Target是否为空)。

您可以尝试这样的事情:
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接收者的弱引用,并且将在收集事件后自动从事件中删除事件处理程序,只要定期引发该事件,就应该防止内存泄漏。

关于c# - 一线: WeakReference-to-a-Lambda Event Handler,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3260211/

10-08 21:23