事件订阅已更改 - InvalidOperationException
Event subscription changed - InvalidOperationException
UI 元素可以订阅按下、按住或释放等事件。因此,我创建了一个对象变量来存储这些信息
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,因为事件订阅者计数已被变了。到现在为止,我只是在块周围放了一个 try-catch。但我想避免原来的问题。
基于每个订阅者都能够在委托中 unsubscribe/subscribe 的事实,我无法使用信号量。此外,我想避免在每个更新周期都创建事件的副本,因为此应用程序在移动设备上 运行。我怎样才能解决这个问题?
也许 Concurrent Dictionary 就足够了?
您可能还需要实施 Custom Event Accessors。
编辑:
错误是由 List<T>.ForEach
语句生成的,其中集合在迭代期间发生了更改。应该使用 for
循环来实现这一点。
UI 元素可以订阅按下、按住或释放等事件。因此,我创建了一个对象变量来存储这些信息
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,因为事件订阅者计数已被变了。到现在为止,我只是在块周围放了一个 try-catch。但我想避免原来的问题。
基于每个订阅者都能够在委托中 unsubscribe/subscribe 的事实,我无法使用信号量。此外,我想避免在每个更新周期都创建事件的副本,因为此应用程序在移动设备上 运行。我怎样才能解决这个问题?
也许 Concurrent Dictionary 就足够了?
您可能还需要实施 Custom Event Accessors。
编辑:
错误是由 List<T>.ForEach
语句生成的,其中集合在迭代期间发生了更改。应该使用 for
循环来实现这一点。