gpt4 book ai didi

c# - 一个类轮 : WeakReference-to-a-Lambda Event Handler

转载 作者:太空狗 更新时间:2023-10-29 17:45:26 24 4
gpt4 key购买 nike

除了多次使用它会违反 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com