..."/> ...">

Home >Backend Development >C++ >Is My `foreach` Loop and Lambda Threading Safe in C#?

Is My `foreach` Loop and Lambda Threading Safe in C#?

Barbara Streisand
Barbara StreisandOriginal
2025-01-22 07:06:16630browse

Is My `foreach` Loop and Lambda Threading Safe in C#?

Thread safety issues of foreach loops and Lambda expressions in C#

Let’s analyze the following code snippet:

<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>

Which code snippet ensures that each thread calls a method on the Foo instance in the same loop iteration as when the thread was created?

In C# 5 and later, both code snippets are safe due to compiler changes to variable definitions within closure scopes. However, prior to C# 5, only the second snippet was safe.

In the first code snippet, the variable f is declared outside the loop and remains visible throughout execution. This means there is only one instance of f in the closure scope. Therefore, different threads accessing f may conflict, causing method invocation errors.

To alleviate this problem, the second code snippet declares a new variable f2 inside the loop. This ensures that each closure scope has its own copy of the reference to the Foo instance, guaranteeing per-thread safe method execution.

The following example demonstrates this 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>

If temporary variables are not used, this code will produce unpredictable and incorrect output. This is because all threads reference the same i variable, and the value of foreach is the last value after the i loop ends.

Therefore, to ensure thread safety, it is best to always create a copy of a local variable when using a Lambda expression within a foreach loop, as shown in the second code snippet.

The above is the detailed content of Is My `foreach` Loop and Lambda Threading Safe in C#?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn