Disclaimer: mes messages sont apparemment toujours verbeux. Si vous connaissez la réponse à la question du titre, n'hésitez pas à simplement y répondre sans lire ma discussion prolongée ci-dessous. Em> le puisque l'utilisation de MAINTENANT, je suis peut-être coupable d'être générique heureux (je vais admettre que cela est souvent vrai); mais il se sent stupide je ne peux pas faire cela car
system.threading.Interlocked.Interlocked. / code> classe fournit Quelques méthodes très utiles pour aider à la rédaction du code de la sécurité thread-Safe. L'une des méthodes les plus complexes est
comparaisonxchange code>, qui peut être utilisée pour calculer un total exécutant pouvant être mis à jour à partir de plusieurs threads. P>
comparaitxchange code> est un peu délicat, je pensais qu'une idée assez courante de fournir des méthodes d'assistance pour cela: p>
Double code> Valeurs uniquement (ou, plus précisément, pour que je dois écrire des versions surchargées de la Les méthodes ci-dessus pour chaque type que je souhaite supporter). Pourquoi je ne peux pas faire cela? P>
interlocked.compeeexchange
T: Classe code> contrainte et Je ne comprends pas pourquoi strong>. Je veux dire, peut-être em> c'est parce qu'il existe déjà des surcharges pour
comparaisonxchange code> qui accepte
int32 code>,
int64 code>,
double code>, etc.; Mais cela ne semble guère une bonne justification. Dans mon cas, par exemple, il serait tout à fait pratique de pouvoir utiliser la méthode
agrégate
3 Réponses :
Je soupçonnerais que essayer de le faire avec un type de valeur ne donnerait probablement pas aux résultats que vous attendez. P>
Vous pouvez, bien sûr, la valeur de la boîte type de la valeur dans un objet interlocked.careeexchange
code> avant de les utiliser. p>
Déversure la boxe des types de valeur comme objet code> serait pas b> travail, réellement. Voir mon premier commentaire à la réponse de Mehrdad.
Les processeurs qui fournissent à Atomic Comparer les instructions d'échange la supportent naturellement comme étant des opérations «de la taille d'un registre» (par exemple, la plus grande instruction de comparaison sur un processeur Intel X64 est Un type de valeur arbitraire peut être potentiellement plus grand que cela et le comparer-l'échange de choses peut ne pas être possible avec une seule instruction. Comparer-l'échange d'un type de référence est facile. Quelle que soit sa taille totale en mémoire, vous comparez et copier un petit pointeur d'une taille connue. Ceci est également vrai pour les types primitifs tels que interlocked.careExchange code> est censé être implémenté avec des instructions atomiques indigènes fournies directement par le processeur. Il est inutile d'avoir quelque chose comme celui-ci Utiliser un
verrouillage code> en interne (il est conçu pour les scénarios sans verrouillage). p>
CMPXCHG16B code> qui fonctionne sur des valeurs 128 bits ). p>
int32 code> et
double code> - tous d'entre eux sont petits. P>
Je pense que cela se concentra au centre de moi une fois que je l'ai lu dans la documentation MSDN peu après avoir posté la question (pour la surcharge accepte les paramètres code> objet code>): "Les objets sont comparés pour l'égalité de référence, plutôt que < Code> Object.equals code>. En conséquence, deux instances en boîte du même type de valeur (par exemple, l'entier 3) semblent toujours être inégaux et aucune opération n'est effectuée. N'utilisez pas cette surcharge avec des types de valeur . " Bien sûr - il ne va pas utiliser la méthode égale code>, mais plutôt vérifier les références elles-mêmes.
Donc, clairement, mon seul choix serait d'écrire toutes ces méthodes surchargées moi-même (pour int code>,
long code>, etc.) après tout - si je voulais vraiment aller aller cette route. À droite?
@Dan: Je ne sais pas comment vous le feriez pour un type de valeur plus grand atomiquement i> sans utiliser de verrouillage code> (code> (échange d'une bande de valeurs entières). Le point de comparer-échange est que c'est atomique; C'est-à-dire qu'il n'y aura pas de point à temps lorsque vous pouvez observer une partie de l'opération est effectué et l'autre partie n'est pas. Mettre un groupe de comparaison-échangers le long de l'autre ne contribuera pas à faire de l'opération globale atomique (chaque partie est atomique, mais l'opération dans son ensemble n'est pas).
@Dan: ignorer mon dernier commentaire. Votre avertissement m'a fait de ne pas lire votre question et j'ai mal compris ce que vous vouliez dire à partir d'une méthode surchargée;). Oui, vous devrez le faire.
@Mehrdad: Je pense que tu m'as perdu. Mon intention n'était pas d'utiliser "un groupe de comparaison-échangers le long de l'autre" ... plutôt de fournir un moyen facile d'effectuer n'importe quel type de Single i> Agrégation atomiquement (par exemple, en résumé des valeurs carrées) .
@Mehrdad: OK, ignore mon dernier commentaire i>.
@Dan: Oui. J'ai dit que juste avant votre commentaire. Vous devrez la mettre en œuvre spécifiquement pour int code>,
long code>, ... soit en utilisant des surcharges ou en cochant
typeof (t) code> et prenant un Piste de code alternatif. Vous ne pourrez pas faire cela avec un seul chemin de code.
Je me demande s'il y aurait eu une difficulté à fournir une paires structure
comparaisonxchange code> pour cela, puisque les processeurs où ce type prendrait 64 bits comportant des instructions de comparaison de 64 bits et ceux où le type prendrait 128 bits ont des instructions de comparaison de 128 bits? Être capable d'échanger deux références à la fois serait plutôt pratique parfois.
Parce que cette surcharge est spécifiquement destinée à comparer et à échanger une référence. Il n'effectue pas de vérification d'égalité à l'aide de la méthode Equals (). Étant donné qu'un type de valeur n'aurait jamais d'égalité de référence avec la valeur que vous comparez contre, je suppose que je suppose qu'ils sont contraints de la classe afin d'éviter toute utilisation abusive. P>
Je parie que votre nom de famille vous donne beaucoup de crédit parmi vos collègues.
C'était un +1 de moi, au fait; Je n'étais pas serré.
Lol ça va, je ne l'ai pas pris comme tel. Très bonne question aussi au fait.