ホームページ > バックエンド開発 > C++ > マルチスレッド C# コードで Foreach ループとクロージャに特別な処理が必要なのはなぜですか?

マルチスレッド C# コードで Foreach ループとクロージャに特別な処理が必要なのはなぜですか?

Patricia Arquette
リリース: 2025-01-22 07:17:13
オリジナル
965 人が閲覧しました

Why Do Foreach Loops and Closures Require Special Handling in Multithreaded C# Code?

マルチスレッド C# の foreach ループとクロージャを理解する

C# のマルチスレッドでは、foreach ループとクロージャーを使用するときに複雑さが生じる可能性があります。 この問題は、foreach ループ内のクロージャがループの反復変数を参照する場合に発生します。

次の例を考えてみましょう:

<code class="language-csharp">var threads = new List<Thread>();
foreach (Foo f in ListOfFoo)
{      
    Thread thread = new Thread(() => f.DoSomething());
    threads.Add(thread);
    thread.Start();
}</code>
ログイン後にコピー

ここで、各スレッドのクロージャは単一の f 変数への参照をキャプチャします。 ループが進行するにつれて、f の値が変化し、予期しない結果が生じます。スレッドが予期しない Foo オブジェクトを操作する可能性があります。

スレッドの安全性の確保

これを回避するには、各反復内で新しいローカル変数を作成します。

<code class="language-csharp">var threads = new List<Thread>();
foreach (Foo f in ListOfFoo)
{      
    Foo f2 = f; // Create a copy for each thread
    Thread thread = new Thread(() => f2.DoSomething());
    threads.Add(thread);
    thread.Start();
}</code>
ログイン後にコピー

各スレッドには独自の独立した参照 (f2) があり、DoSomething() が正しい Foo インスタンスで呼び出されることが保証されます。

C# 5 以降

C# 5 以降では動作が若干変更されました。 コンパイラーは、foreach 変数がループのスコープ外にある場合でも、ループのスコープ内で事実上宣言されているものとして扱います。 したがって、上記の両方のコード スニペットは、C# 5 以降のバージョンではスレッド セーフです。 ただし、明示的なコピーは、明確さと下位互換性のために依然として良い習慣です。

以上がマルチスレッド C# コードで Foreach ループとクロージャに特別な処理が必要なのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート