Maison > développement back-end > C++ > Ma boucle « foreach » et mon thread Lambda sont-ils sûrs en C# ?

Ma boucle « foreach » et mon thread Lambda sont-ils sûrs en C# ?

Barbara Streisand
Libérer: 2025-01-22 07:06:16
original
670 Les gens l'ont consulté

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

Problèmes de sécurité des threads des boucles foreach et des expressions Lambda en C#

Analysons l'extrait de code suivant :

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

Quel extrait de code garantit que chaque thread appelle une méthode sur l'instance Foo dans la même itération de boucle que lors de la création du thread ?

En C# 5 et versions ultérieures, les deux extraits de code sont sécurisés en raison des modifications apportées par le compilateur aux définitions de variables dans les portées de fermeture. Cependant, avant C# 5, seul le deuxième extrait était sûr.

Dans le premier extrait de code, la variable f est déclarée en dehors de la boucle et reste visible tout au long de l'exécution. Cela signifie qu'il n'y a qu'une seule instance de f dans la portée de fermeture. Par conséquent, différents threads accédant à f peuvent entrer en conflit, provoquant des erreurs d'invocation de méthode.

Pour atténuer ce problème, le deuxième extrait de code déclare une nouvelle variable f2 à l'intérieur de la boucle. Cela garantit que chaque portée de fermeture possède sa propre copie de la référence à l'instance Foo, garantissant ainsi une exécution de méthode sécurisée par thread.

L'exemple suivant illustre ce problème :

<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>
Copier après la connexion

Si les variables temporaires ne sont pas utilisées, ce code produira une sortie imprévisible et incorrecte. En effet, tous les threads font référence à la même variable i et la valeur de foreach est la dernière valeur après la fin de la boucle i.

Par conséquent, pour garantir la sécurité des threads, il est préférable de toujours créer une copie d'une variable locale lors de l'utilisation d'une expression Lambda dans une boucle foreach, comme indiqué dans le deuxième extrait de code.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal