Ben*_*udo 9 .net c# lambda weak-references event-handling
除了多次使用它会违反DRY原则这个事实之外,你能否看到这种单线的缺点?这似乎很简单,但我没有看到其他人提出它的事实让我想知道它是否有缺点.
这段代码创建一个方法的WeakReference,然后注册一个调用引用目标的事件处理程序.
SomeEvent += (sender, e) => ((Action)(new WeakReference((Action)ProcessEvent)).Target)();
Run Code Online (Sandbox Code Playgroud)
谢谢,
本
Qua*_*ter 12
我不认为这种模式符合您的期望.您是否试图阻止事件持有对当前对象的引用以防止内存泄漏?lambda表达式将捕获值this以进行求值ProcessEvent(假设ProcessEvent是一个实例方法),因此您仍然会有泄漏.这段代码和做的一样SomeEvent += (sender, e) => ProcessEvent();.
您可能正在尝试做更像这样的事情(这也不是您想要的):
var reference = new WeakReference((Action)ProcessEvent);
SomeEvent += (sender, e) => ((Action)reference.Target)();
Run Code Online (Sandbox Code Playgroud)
现在lambda表达式将捕获WeakReference,因此您将没有强引用this.不幸的是,没有别的东西引用从ProcessEvent创建的委托,因此即使它还this活着,它也会在下一个GC上删除.(这也不会检查Target是否为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;
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
SomeEvent += MakeWeakHandler(ProcessEvent, h => SomeEvent -= h);
Run Code Online (Sandbox Code Playgroud)
这将保留对ProcessEvent的接收者的弱引用,并将在收集事件后自动从事件中删除事件处理程序,这可以防止内存泄漏,只要事件是定期引发的.
| 归档时间: |
|
| 查看次数: |
3411 次 |
| 最近记录: |