Container enumerieren, und elemente löschen?



  • Hallo, hier der code^:)

    foreach (KeyValuePair<Guid, ClientSession> ClientSession in m_ClientSessions)
                    {
                        TimeSpan LastClientPolleTime = DateTime.Now - ClientSession.Value.LifeSign;
                        if (LastClientPolleTime.Seconds > 30)
                        {
                            clEvent("Client Timeout", ClientSession.Key);
                            m_ClientSessions.Remove(ClientSession.Key);
                        }
                    }
    

    Wenn ich nun in mitten der for schleife ein element aus der liste lösche welche iteriert wird gibt ne Exception (was mit auch klar ist).

    Wie könnte ich das elegant lösen, das ich Elemente aus der liste löschen kann, und die weiteren iteriert werden?



  • Erst sammeln der Keys zum entfernen und anschliessend alle gesammelten Keys aus dem Container löschen. Ich nehmen an es ist ein Dictionary<K, V>.



  • ja ist ne dictonary;) ja die lösung mit maskieren und danach löschen hab ich mir auch überlegt, aber das wären ja dann zwei schleifen. Wobei mich mich frage das ich ja in der nächsten schleifen auch mit abfrage ob maskiert und dann remove mache... wäre ja wieder das gleiche Problem oder?



  • Du kannst die Werte vorher in eine andere Liste packen und die dann durch gehen.

    List<KeyValuePair<Guid, ClientSession>> key_liste = new List<KeyValuePair<Guid, ClientSession>>(m_ClientSessions);
    foreach (KeyValuePair<Guid, ClientSession> ClientSession in key_liste)
    {
        TimeSpan LastClientPolleTime = DateTime.Now - ClientSession.Value.LifeSign;
        if (LastClientPolleTime.Seconds > 30)
        {
           clEvent("Client Timeout", ClientSession.Key);
           m_ClientSessions.Remove(ClientSession.Key);
        }
    }
    


  • C#Noob schrieb:

    ja ist ne dictonary;) ja die lösung mit maskieren und danach löschen hab ich mir auch überlegt, aber das wären ja dann zwei schleifen.

    Na ja, es ist aber trotzdem relativ effizient, da würde ich mir also keine zu großen Sorgen machen, und es ist auch nicht viel Code:

    var del = new List<Guid>();
    
    foreach(var kvp in m_ClientSessions)
        if (shallDelete(kvp))
            del.Add(kvp.Key);
    
    del.ForEach(m_ClientSessions.Remove);
    

    Um aus einer Liste zu löschen gibt's übrigens die Methode `RemoveAll`, weil der obige Ansatz dort wesentlich ineffizienter wäre.


Anmelden zum Antworten