Sont C# délégués thread-safe?
Si vous avez une instance de classe avec un membre délégué de la variable et plusieurs threads invoquer que délégué (à supposer qu'il pointe vers une méthode longue), est-il un problèmes de contention?
Avez-vous besoin de verrouiller autour du délégué ou est il sans danger pour chaque thread pour appeler la méthode de la déléguée des points de, car chaque thread obtient sa propre pile d'appel?
Vous devez vous connecter pour publier un commentaire.
Concernant l'invocation de la déléguer la réponse est oui.
Invoquant un délégué est thread-safe, car les délégués sont immuables. Cependant, vous devez vous assurer qu'un délégué existe tout d'abord. Ce contrôle peut exiger certains mécanismes de synchronisation en fonction du niveau de sécurité souhaité.
Par exemple, les activités suivantes pourraient jeter un
NullReferenceException
siSomeDelegate
ont été mis à null par un autre thread entre le nul de la vérification et de l'invocation.La suite est un peu plus fort. Ici, nous sommes en exploitant le fait que les délégués sont immuables. Même si un autre thread modifie
SomeDelegate
le code est harded pour éviter que satanésNullReferenceException
.Toutefois, cela peut entraîner le délégué ne jamais être exécutée si
SomeDelegate
a été attribué une valeur non nulle dans un autre thread. Cela a à voir avec une subtile de la mémoire de la barrière de problème. Ce qui suit est la méthode la plus sûre.Concernant l'exécution de la méthode référencée par le délégué, la réponse est non.
Vous devrez fournir votre propre thread-safety guarentees via l'utilisation de mécanismes de synchronisation. C'est parce que le CLR ne fournissent pas automatiquement fil-sécurité guarentees pour l'exécution des délégués. Cela pourrait être le cas que la méthode ne nécessite aucun de synchronisation pour le rendre sûr, surtout si elle n'a jamais accès à l'état partagé. Cependant, si la méthode de la lecture ou de l'écriture à partir d'une variable partagée ensuite, vous aurez à examiner comment se prémunir contre les accès simultanés à partir de plusieurs threads.
public event SomeHandler MyEvent = { }
et il est assuré de ne pas être null.SomeDelegate = null
.Interlocked.CompareExchange(ref SomeDelegate, null, null)
avecVolatile.Read(ref SomeDelegate)
. Voir cette question.Non, ils ne sont pas thread-safe et oui, vous aurez à gérer la simultanéité vous-même.
Directement à partir de la documentation de MulticastDelegate:
La Délégué classe contient les mêmes informations, donc là vous l'avez.
La modification d'un événement n'est pas thread-safe, mais en invoquant un délégué.
Depuis un délégué est immuable, il n'est pas thread-safe. Voir les remarques ici MSDN Délégué de classe:
Emprunté ici:
Dans le CLR Via C# Richter souligne quelques points subtils sur l'événement invocation en multi-thread classes:
Un délégué de la chaîne est immuable; une nouvelle chaîne est créé pour remplacer le premier.
Un délégué de la chaîne avec zéro abonnés est null.
Que signifie (si votre événement est public), il peut la transition à partir de la valeur null à la non-nul et vice versa, à tout moment.