Maison >développement back-end >C++ >L'accès aux variables dans les boucles Foreach dans les expressions C# Lambda est-il thread-safe ?

L'accès aux variables dans les boucles Foreach dans les expressions C# Lambda est-il thread-safe ?

DDD
DDDoriginal
2025-01-22 07:11:08287parcourir

Is Accessing Variables in Foreach Loops Within C# Lambda Expressions Thread-Safe?

Expressions C# Lambda et foreach Sécurité des threads de boucle

Cet article examine la sécurité des threads lors de l'accès aux variables dans les boucles foreach dans les expressions lambda C#, en se concentrant sur les différences entre les versions C#.

Comportement pré-C# 5

Dans les versions C# antérieures à 5, accéder directement aux variables déclarées en dehors d'une boucle foreach dans une expression lambda utilisée dans un contexte multithread (par exemple, dans un constructeur Thread) est dangereux. En effet, la variable itératrice de la boucle foreach est partagée entre toutes les itérations. Par conséquent, plusieurs threads peuvent accéder et modifier la même variable, conduisant à des résultats imprévisibles et incorrects. Les conditions de course sont très probables.

C# 5 et versions ultérieures

À partir de C# 5, la gestion par le compilateur des itérateurs dans les boucles foreach améliore considérablement la sécurité des threads. Le compilateur crée désormais effectivement une nouvelle instance de la variable itérateur pour chaque itération. Cela signifie que chaque expression lambda capture une copie unique de la variable, éliminant ainsi le risque de conditions de concurrence critique. Par conséquent, dans C# 5 et les versions ultérieures, les deux approches (utilisant une seule variable itératrice déclarée à l'extérieur ou à l'intérieur de la boucle) sont généralement considérées comme thread-safe.

Exemple illustratif (comportement dangereux pré-C#5)

L'extrait de code suivant met en évidence le comportement dangereux dans les versions antérieures à C#5 :

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

L'exécution de ce code produira probablement des sorties où les valeurs de i ne sont pas séquentiellement correctes, démontrant la condition de concurrence critique. Chaque thread capture la même i variable, et sa valeur peut changer au moment où un thread exécute son expression lambda.

Conclusion

Alors que les anciennes versions C# nécessitaient une gestion minutieuse des variables d'itérateur dans les boucles foreach dans les expressions lambda pour garantir la sécurité des threads, C# 5 et les versions ultérieures atténuent ce problème grâce aux optimisations du compilateur. Cependant, il est toujours recommandé d'être attentif aux problèmes de concurrence potentiels, en particulier lorsqu'il s'agit de ressources partagées au sein d'expressions lambda, quelle que soit la version C#. L'utilisation de variables locales au sein de chaque itération reste une bonne pratique pour plus de clarté et de maintenabilité.

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!

Déclaration:
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