事件订阅已更改 - InvalidOperationException

时间:2016-06-06 07:00:23

标签: c# events action monogame

UI Elements可以订阅按下,按住或发布等事件。因此,我创建了一个对象变量来存储这些信息

        private Dictionary<TouchListenerType, List<Action<int, float, Vector2>>> touchData = new Dictionary<TouchListenerType, List<Action<int, float, Vector2>>>();

每个更新周期我迭代每个提供的输入并将其委托给订阅者。

        try
        {
            for (int currentTouchIndex = touchCollections.Count - 1; currentTouchIndex >= 0; currentTouchIndex--)
            {
                Vector2 position = MapInput(touchCollections[currentTouchIndex].Position);
                if (touchCollections[currentTouchIndex].State == TouchLocationState.Moved &&
                    touchData[TouchListenerType.Move].Count > 0)
                    touchData[TouchListenerType.Move].ForEach(d => d.Invoke(touchCollections[currentTouchIndex].Id, touchCollections[currentTouchIndex].Pressure, position));
                else if (touchCollections[currentTouchIndex].State == TouchLocationState.Pressed &&
                    touchData[TouchListenerType.Press].Count > 0)
                    touchData[TouchListenerType.Press].ForEach(d => d.Invoke(touchCollections[currentTouchIndex].Id, touchCollections[currentTouchIndex].Pressure, position));
                else if (touchCollections[currentTouchIndex].State == TouchLocationState.Released &&
                    touchData[TouchListenerType.Release].Count > 0)
                    touchData[TouchListenerType.Release].ForEach(d => d.Invoke(touchCollections[currentTouchIndex].Id, touchCollections[currentTouchIndex].Pressure, position));
            }
        } catch { } //Enumeration could have been changed

如果订阅者决定取消订阅或根据提供的输入添加其他订阅,则会抛出异常 System.InvalidOperationException ,因为事件订阅者计数已更改。直到现在我只是在街区附近试一试。但我想避免原来的问题。

基于每个订阅者都能够在代理中取消订阅/订阅的事实,我无法使用信号量。此外,我还想避免在每个更新周期创建事件的副本,因为此应用程序在移动设备上运行。我怎么能解决这个问题?

1 个答案:

答案 0 :(得分:1)

也许Concurrent Dictionary就足够了?

您可能还需要实施Custom Event Accessors

编辑:

错误由List<T>.ForEach语句生成,其中集合在迭代期间发生更改。应该使用for循环来实现此目的。