事件订阅的性能注意事项

时间:2013-01-01 16:56:30

标签: c# performance events observer-pattern

考虑以下代码:

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的事件,这样它就可以对游戏环境“做出”适当的改变(这是通过进一步传播)负责执行每个特定指令的对象的事件,如Observer模式)。

现在考虑到我的所有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子集。

1 个答案:

答案 0 :(得分:0)

  

然而,这让我很难在某处列出所有游戏的项目

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

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)
    }

}

之后,您将所有项目类派生自名为“ItemBase”的类。在ItemBases构造函数中,您可以这样称呼:

ItemManager.Instance.RegisterItem(this);

因此您无需手动添加每个项目。有关单例模式的更多信息,请查看此处:http://msdn.microsoft.com/en-us/library/ff650316.aspx

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