ホームページ >バックエンド開発 >C++ >C# マルチスレッド クロージャで「foreach」変数を直接使用するのは安全ですか?

C# マルチスレッド クロージャで「foreach」変数を直接使用するのは安全ですか?

Barbara Streisand
Barbara Streisandオリジナル
2025-01-22 06:56:12718ブラウズ

Is Using the `foreach` Variable Directly in C# Multi-threaded Closures Safe?

foreach C# の変数とマルチスレッド クロージャ: 安全ですか?

C# で foreach を使用してコレクションをループする場合、特にマルチスレッド環境では、反復変数のスコープと動作を理解することが重要です。

次のコード スニペットは、マルチスレッドで foreach 変数をクロージャー引数として直接使用するのが安全かどうか、および反復ごとにローカル コピーを作成する必要があるかどうかを調べます。

C# 5 より前のバージョン

C# 5 より前のバージョンでは、foreach 変数はループの外で宣言されていました。これは、単一の変数インスタンスがすべての反復で共有されることを意味します。

最初のコード スニペットを考えてみましょう:

<code class="language-csharp">foreach (Foo f in ListOfFoo)
{      
    Thread thread = new Thread(() => f.DoSomething());
    threads.Add(thread);
    thread.Start();
}</code>

この例では、f 変数はループの反復中に作成されたすべてのスレッド間で共有されます。これにより、複数のスレッドが Foo の異なるインスタンスのメソッドを呼び出したり、同じインスタンスのメソッドを複数回呼び出したりする可能性があるため、予測できない結果が生じる可能性があります。

このような問題を回避するには、2 番目のコード スニペットに示すように、反復ごとに f 変数のローカル コピーを作成することをお勧めします。

<code class="language-csharp">foreach (Foo f in ListOfFoo)
{      
    Foo f2 = f;
    Thread thread = new Thread(() => f2.DoSomething());
    threads.Add(thread);
    thread.Start();
}</code>

C# 5 以降

C# 5 では重要な変更が導入されています。 C# 5 以降では、

変数はループ スコープ内で定義されます。これは、各反復に変数の独自のインスタンスがあることを意味します。 foreach

したがって、

2 つのコード スニペットは等価で安全になります。各スレッドのクロージャースコープ内に独自の インスタンスが存在するようになり、混乱や不一致のリスクがなくなりました。 f

以上がC# マルチスレッド クロージャで「foreach」変数を直接使用するのは安全ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。