2016-06-06 9 views
1

UI-Elemente können Ereignisse wie drücken, halten oder freigeben abonnieren. Deshalb habe ich eine Objektvariable diejenigen InformationenEreignissubskription geändert - InvalidOperationException

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

Jedes Update-Zyklus ich über jeden Eingang versehen iterieren zu speichern und an die Teilnehmer zu übertragen.

 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 

Wenn ein Teilnehmer einen anderen Abonnement abzubestellen entscheidet oder hinzufügen, basierend auf dem mitgelieferten Eingabe, die Ausnahme System.InvalidOperationException wird geworfen, weil das Ereignis Teilnehmerzahl geändert wurde. Bis jetzt habe ich nur einen Versuch um den Block herum gemacht. Aber ich möchte das ursprüngliche Problem vermeiden.

Aufgrund der Tatsache, dass jeder Abonnent in der Delegierten abmelden/abonnieren kann, kann ich nicht mit Semaphoren arbeiten. Ich möchte auch vermeiden, eine Kopie des Ereignisses jeden Aktualisierungszyklus zu erstellen, da diese Anwendung auf mobilen Geräten ausgeführt wird. Wie kann ich dieses Problem lösen?

Antwort

1

Vielleicht reicht eine Concurrent Dictionary?

Möglicherweise müssen Sie auch Custom Event Accessors implementieren.

Edit:

Der Fehler durch die Anweisung erzeugt wird, wo die Sammlung während der Iteration geändert wird. Eine for Schleife sollte verwendet werden, um dies zu ermöglichen.

+0

Ein Schloss ist die Gleichung eines Monitors. Aber vielleicht sollte ich wirklich Ereignisse statt der Aktionen verwenden. –

+1

Erhalten Sie einen Fehler während der Liste .ForEach? Vielleicht sollten Sie es in eine 'for'-Schleife ändern, damit sich seine Größe während der Iteration ändern kann. –

+0

Warum habe ich nicht darüber nachgedacht. Ofc. das ist die Lösung .... Danke –

Verwandte Themen