C# 事件订阅的性能注意事项

C# 事件订阅的性能注意事项,c#,performance,events,observer-pattern,C#,Performance,Events,Observer Pattern,考虑以下代码: class GameEventsManager { public void StartGameEvent(GameEvent TheGameEvent) { SubscribeToGameEvent(TheGameEvent); TheGameEvent.Begin(); UnsubscribeToGameEvent(TheGameEvent); } private void Subs

考虑以下代码:

class GameEventsManager
{
    public void StartGameEvent(GameEvent TheGameEvent)
    {       
        SubscribeToGameEvent(TheGameEvent);
        TheGameEvent.Begin();
        UnsubscribeToGameEvent(TheGameEvent);
    }

    private void SubscribeToGameEvent(GameEvent TheGameEvent)
    {
        TheGameEvent.OnPlaySound += OnPlaySound;
        TheGameEvent.OnShowWrittenItem += OnShowWrittenItem;
            ...
    }

    private void UnsubscribeToGameEvent(GameEvent TheGameEvent)
    {
        TheGameEvent.OnPlaySound -= OnPlaySound;
        TheGameEvent.OnShowWrittenItem -= OnShowWrittenItem;
            ...
    }
}
GameEvent基本上就是这样一个类:当调用Begin()时,它会引发传递给GameEventManager的事件,以便对游戏环境进行适当的更改(这是通过将事件进一步传播到负责执行每个特定指令的对象,如观察者模式中)

现在考虑到我的所有InventoryItems(可以触发事件,如OnConsume、OnUse)都是它们特定类中的静态字段。虽然这看起来有点粗糙,但我觉得能够:

AddItem(WrittenItems.NoteFromKing) //NoteFromKing is a static field in WrittenItems
让事情变得简单了很多,考虑到我正在做一个相当复杂的游戏,这是一个受欢迎的景象

然而,这使得我很难在某个地方列出游戏的所有项目,以防需要。这就引出了我的问题:

LevelManager负责管理玩家与关卡中特定项目交互的时间等事项,它告诉GameEventsManager在需要时运行特定GameEvent。GameEventsManager然后订阅GameEvent,启动它,然后取消订阅。我是否希望在遵循此子项时看到明显的性能问题抄写/运行/取消订阅模式?最终,经理可能会订阅/取消订阅GameEvent中的大约20个事件

如果订阅/取消订阅机制很慢,我可以创建一个在游戏初始化时运行的订阅进程,但这会迫使我构建一个额外的结构,列出所有项目

所以,简而言之,我想知道我是否应该期待这种实现会有相当大的放缓。或者更准确地说,如果订阅了大约20个活动,然后取消订阅会有相当大的放缓

语言是C#,使用Unity 4下的.NET 2.0子集

然而,这使得我很难在某个地方列出游戏的所有项目

为什么?您可以创建一个ItemManager(它是一个单例):

因此,您不必手动添加每一项。有关singleton模式的更多信息,请查看此处:


这样做的一个小好处是,您可以在GameManager和ItemManager之间实现常规通信。

订阅/取消订阅在一个时间段内发生了多少次?不应该很成功。为什么不使用项目作为常量并将其注册到单个(静态)中数组?订阅/取消订阅非常罕见;这实际上取决于播放器的很多功能,但它不是一帧一帧的东西。我以前使用字典来存储项目。我不得不在两个不同的地方添加关于每个项目的信息,这感觉有点不对。我读了很多关于人们是如何讨厌单例和单例模式的我甚至没有考虑过这样的解决方案。让我们看看我是否可以优雅地做些什么。从技术上来说,我认为,一个简单的静态类,比如InventoryItems,它的集合也是公共的和静态的,也可以工作。InventoryItems.AddItem(这个)在构造函数内部。为了避免单例的全局状态,我选择了一个更简单的解决方案,它与其他Unity组件的构建方式更为相似。这样更干净、更简单。
public class ItemManager
{
    private static volatile ItemManager _instance;
    private static object syncRoot = new Object();

    private ObservableCollection<ItemBase> _registeredItems = new ObservableCollection<ItemBase>();
    private ItemManager()
    {
    }

    public ItemManager Instance
    {
        get
        {
             if (instance == null) 
             {
                 lock (syncRoot) 
                 {
                     if (instance == null) 
                         instance = new ItemManager();
                 }
             } 
             return instance;
        }
    }

    public void RegisterItem(ItemBase item)
    {
        _registeredItems.Add(item);
        // Do some stuff here, subscribe events, etc.
    }

    public void UnregisterItem(item)
    {
        // Do some stuff here, unregister events, etc.
        _registeredItems.Remove(item)
    }

}
ItemManager.Instance.RegisterItem(this);