MulticastDelegate.GetInvocationList()分配.有办法解决这个问题吗?

本文关键字:解决 问题 GetInvocationList 分配 MulticastDelegate | 更新日期: 2023-09-27 18:10:01

是否有可能调用MulticastDelegate并处理每个附加处理程序的返回值而不分配任何内存?

在正常情况下,MulticastDelegate.GetInvocationList()分配的Delegate[]可以忽略不计。然而,在某些情况下,尽量减少拨款是很重要的。例如,在紧凑框架上运行的Xbox游戏中,每分配1MB就会触发一个集合和严重的帧率问题。

在使用CLR Profiler查找并消除游戏过程中的大多数分配后,我留下了50%的垃圾是由Farseer Physics碰撞回调调用引起的。它需要迭代完整的调用列表,因为用户可以返回false来取消来自任何附加处理程序的碰撞响应(并且调用委托而不使用GetInvocationList()只是返回最后附加处理程序的结果)。

作为参考,下面是所讨论的Farseer代码:

// Report the collision to both participants. Track which ones returned true so we can
// later call OnSeparation if the contact is disabled for a different reason.
if (FixtureA.OnCollision != null)
    foreach (OnCollisionEventHandler handler in FixtureA.OnCollision.GetInvocationList())
        enabledA = handler(FixtureA, FixtureB, this) && enabledA;

MulticastDelegate.GetInvocationList()分配.有办法解决这个问题吗?

我找到了一个解决方案,以List<Delegate>代替MulticastDelegate的形式。

我需要在每一帧MulticastDelegate中调用GetInvocationList()

private List<Action> _actions;
public event Action ActionsEvent
{
    add
    {
        if (_actions == null)
            _actions = new List<Action>();
        _actions.Add(value);
    }
    remove
    {
        if (_actions != null)
        {
            _actions.Remove(value);
            if (_actions.Count == 0)
                _actions= null;
        }
    }
}