Heim >Backend-Entwicklung >C++ >Wie gehe ich mit der 'Sammlung modifiziert', die Aufzählungsoperation kann keine Fehler in Multithread -Umgebungen ausführen?

Wie gehe ich mit der 'Sammlung modifiziert', die Aufzählungsoperation kann keine Fehler in Multithread -Umgebungen ausführen?

DDD
DDDOriginal
2025-02-02 03:46:10421Durchsuche

How to Handle

adressieren "Sammlung geändert: Aufzählungsoperation kann fehlschlagen" Fehler

Der Fehler "Die Sammlung wurde geändert; Aufzählungsoperation kann möglicherweise nicht ausgeführt" entsteht, wenn eine Sammlung geändert wird, während sie iteriert werden, was zu unvorhersehbarem Verhalten führt. Dies geschieht häufig in Multithread -Szenarien, in denen mehrere Threads gleichzeitig auf die gleiche Sammlung zugreifen und dieselbe Sammlung ändern.

Dieser spezifische Fehler manifestiert sich in der Methode NotifySubscribers(), wobei auf das subscribers -Dictionary in einer foreach -Schleife zugegriffen wird. Gleichzeitige Modifikationen an diesem Wörterbuch (z. B. Client -Abonnements oder Abmeldungen) Die Aufzählung ungültig.

Lösung: Implementierung der Thread -Sicherheit

Um dies zu beheben, ist die Gewindesicherheit für das subscribers Wörterbuch von entscheidender Bedeutung. Es werden zwei Ansätze empfohlen:

  1. Verwenden Sie ConcurrentDictionary: Ersetzen Sie das Standardwörterbuch durch ConcurrentDictionary<TKey, TValue>. Diese Datenstruktur ist von Natur aus mit Thread-Sicherheit und verhindert den Fehler.

  2. Erstellen einer Kopie für die Iteration: Vor der foreach -Schule erstellen Sie eine Kopie der Werte des subscribers -Dotionswörterbuchs mit subscribers.Values.ToList(). Dies schafft einen Schnappschuss, der durch nachfolgende Modifikationen am ursprünglichen Wörterbuch nicht beeinflusst wird, um eine sichere Aufzählung zu gewährleisten.

Code -Beispiele:

Hier ist die für die Verwendung NotifySubscribers(): ConcurrentDictionary modifizierte

-Methode
<code class="language-csharp">public void NotifySubscribers(DataRecord sr)
{
    foreach (Subscriber s in subscribers.Values) // subscribers is now a ConcurrentDictionary
    {
        try
        {
            s.Callback.SignalData(sr);
        }
        catch (Exception e)
        {
            DCS.WriteToApplicationLog(e.Message, System.Diagnostics.EventLogEntryType.Error);
            UnsubscribeEvent(s.ClientId);
        }
    }
}</code>

Und hier ist die Version mit ToList(), um eine sichere Kopie zu erstellen:

<code class="language-csharp">public void NotifySubscribers(DataRecord sr)
{
    foreach (Subscriber s in subscribers.Values.ToList())
    {
        try
        {
            s.Callback.SignalData(sr);
        }
        catch (Exception e)
        {
            DCS.WriteToApplicationLog(e.Message, System.Diagnostics.EventLogEntryType.Error);
            UnsubscribeEvent(s.ClientId);
        }
    }
}</code>

Durch die Implementierung einer dieser Lösungen sorgen Sie sicher und verhindern, dass der Fehler "Sammlung geändert wurde ...", was zu robusteren und zuverlässigeren Code führt.

Das obige ist der detaillierte Inhalt vonWie gehe ich mit der 'Sammlung modifiziert', die Aufzählungsoperation kann keine Fehler in Multithread -Umgebungen ausführen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn