2010-07-20 5 views
3

J'ai un code hérité qui utilise Interlocked.Equals pour comparer les valeurs. Les valeurs peuvent être deux booléens ou peuvent comparer un tableau de structs à null. Resharper se plaint de Interlocked.Equals disant "accès à un membre statique d'un type via un type dérivé". Je sais que Equals n'est pas un membre de la classe Interlocked, mais plutôt un membre de la classe d'objets. La comparaison se passe dans un thread donc je suppose que le codeur d'origine voulait faire la comparaison comme une opération atomique d'où l'utilisation de Interlocked. Puisque object.Equals n'est pas atomique, quel est le bon, thread sûr, façon de faire ce genre de comparaisons? Notez que la plupart des données sont statiques et que certaines sont statiques.Ce qu'il faut utiliser à la place de Interlocked.Equals

+0

Quels sont les types d'objets et comment sont-ils utilisés ailleurs? – ULysses

+0

Je me demande combien de temps le développeur d'origine a continué à utiliser Interlocked.Equals, en supposant qu'il doit s'agir d'une fonction de comparaison "sûre" valide car elle était interverrouillée et compilée. –

+0

@Dan: Apparemment depuis longtemps; J'ai trouvé Interlocked.Equals partout dans de nombreux threads différents. :(Je ne suis pas un expert en threading, mais au moins je sais que je ne suis pas un expert –

Répondre

5

Les lectures uniques de booléens ou de références d'objets sont atomiques. Donc, si vous comparez une valeur partagée à une variable constante ou locale, aucun "inter-verrouillage" n'est nécessaire. Comme Jon l'a indiqué, vous devrez utiliser Interlocked.CompareExchange pour vous assurer de lire la dernière valeur écrite, à moins que les variables partagées soient volatile. Si les deux comparaisons sont partagées, vous aurez besoin d'un verrou réel.

Il n'y a pas moyen de comparer atomiquement deux valeurs partagées AFAIK.

Mise à jour:

Je recommande la mise en place de verrous explicites pour les données partagées. Gardez à l'esprit que le code d'origine était complètement cassé, alors n'ayez pas peur de le changer.

Si vous y pensez, que feriez-vous du résultat de la comparaison? Cela n'a pas vraiment de sens. dès que vous avez le résultat, il pourrait être faux. Un verrou aurait besoin d'être tenu plus longtemps que juste pour que la comparaison puisse être utile pour quoi que ce soit.

+9

Atomique! = Volatile. Vous pourriez finir par lire des données périmées. –

+0

Oui, certaines valeurs sont partagées Je vais ajouter ce détail à mes questions –

+0

@Jon: Vous avez raison, ma réponse a été mise à jour –

6

Vous ne pouvez pas faire toute la comparaison atomique, mais ce n'est pas vraiment l'atomicité qui vous intéresse. C'est la volatilité, je suppose. C'est ce qui garantit que lorsque vous lisez une valeur, vous obtenez certainement la dernière version, plutôt que de voir une valeur était valide à un moment donné dans le passé, mais ne peut pas être. Si vous vraiment besoin d'atomicité à travers la partie lire/lire/comparer, je soupçonne que vous aurez besoin de verrouillage.

Vous pouvez utiliser Interlocked.CompareExchange pour vous assurer d'avoir lu la valeur la plus récente.

Avez-vous absolument besoin d'utiliser un filetage sans blocage en premier lieu? Je suggère fortement soit de construire sur des structures plus grandes (par exemple des extensions parallèles) ou simplement d'utiliser des verrous pour des données partagées (ce qui devrait être évité si possible de toute façon).

+0

Cela aurait du être "tableau de structures" Désolé, mauvais montage de ma part Je l'ai corrigé dans ma question –

+0

@Bill W: Okay, enlevé. –

Questions connexes