是否可以调用
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;
我找到了一个解决方案,将
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;
}
}
}