Heim >Backend-Entwicklung >C++ >Ist meine „foreach'-Schleife und mein Lambda-Threading in C# sicher?
Thread-Sicherheitsprobleme von foreach
Schleifen und Lambda-Ausdrücken in C#
Lassen Sie uns das folgende Code-Snippet analysieren:
<code class="language-csharp">foreach (Foo f in ListOfFoo) { Thread thread = new Thread(() => f.DoSomething()); threads.Add(thread); thread.Start(); }</code>
<code class="language-csharp">foreach (Foo f in ListOfFoo) { Foo f2 = f; Thread thread = new Thread(() => f2.DoSomething()); threads.Add(thread); thread.Start(); }</code>
Welches Code-Snippet stellt sicher, dass jeder Thread eine Methode auf der Foo
-Instanz in derselben Schleifeniteration aufruft wie bei der Erstellung des Threads?
In C# 5 und höher sind beide Codefragmente aufgrund von Compileränderungen an Variablendefinitionen innerhalb von Abschlussbereichen sicher. Vor C# 5 war jedoch nur das zweite Snippet sicher.
Im ersten Codeausschnitt wird die Variable f
außerhalb der Schleife deklariert und bleibt während der gesamten Ausführung sichtbar. Dies bedeutet, dass es im Abschlussbereich nur eine Instanz von f
gibt. Daher kann es zu Konflikten zwischen verschiedenen Threads, die auf f
zugreifen, kommen, was zu Fehlern beim Methodenaufruf führen kann.
Um dieses Problem zu lindern, deklariert der zweite Codeausschnitt eine neue Variable f2
innerhalb der Schleife. Dadurch wird sichergestellt, dass jeder Abschlussbereich über eine eigene Kopie des Verweises auf die Foo
-Instanz verfügt, wodurch eine sichere Methodenausführung pro Thread gewährleistet wird.
Das folgende Beispiel veranschaulicht dieses Problem:
<code class="language-csharp">static void Main() { int[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; foreach (int i in data) { new Thread(() => Console.WriteLine(i)).Start(); } Console.ReadLine(); }</code>
Wenn keine temporären Variablen verwendet werden, führt dieser Code zu unvorhersehbaren und falschen Ausgaben. Dies liegt daran, dass alle Threads auf dieselbe i
-Variable verweisen und der Wert von foreach
der letzte Wert nach dem Ende der i
-Schleife ist.
Um die Thread-Sicherheit zu gewährleisten, ist es daher am besten, immer eine Kopie einer lokalen Variablen zu erstellen, wenn Sie einen Lambda-Ausdruck innerhalb einer foreach
-Schleife verwenden, wie im zweiten Codeausschnitt gezeigt.
Das obige ist der detaillierte Inhalt vonIst meine „foreach'-Schleife und mein Lambda-Threading in C# sicher?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!