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

问题描述 投票:0回答:1

是否可以调用

MulticastDelegate
并处理每个附加处理程序的返回值而不分配任何内存?

背景

在正常事物的方案中,

Delegate[]
分配的
MulticastDelegate.GetInvocationList()
可以忽略不计。然而,在某些情况下,最小化分配很重要。例如,在紧凑型框架上运行的 Xbox 游戏的游戏过程中,每分配 1MB 就会触发一次收集和严重的帧速率故障。

在使用 CLR Profiler 搜索并消除游戏过程中的大部分分配后,我剩下 50% 的垃圾是由 Farseer 物理碰撞回调调用引起的。它需要迭代完整的调用列表,因为用户可以返回

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;
c# delegates garbage-collection farseer
1个回答
0
投票

我找到了一个解决方案,将

MulticastDelegate
替换为
List<Delegate>

我需要每帧调用

GetInvocationList()
几帧
MulticastDelegate

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;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.