"Une référence à un domaine volatile ne sera pas considérée comme volatile" implications
le code suivant
using System.Threading;
class Test
{
volatile int counter = 0;
public void Increment()
{
Interlocked.Increment(ref counter);
}
}
augmente l'avertissement de compilateur suivant:
"A reference to a volatile field will not be treated as volatile"
est-ce que je fais quelque chose de mal ici pour élever cet avertissement? Pourquoi le compilateur m'avertir à ce sujet?
4 réponses
vous ne faites rien de mal. Selon la documentation :
un champ volatile ne devrait pas normalement être transmis en utilisant un ref ou un out paramètre, puisqu'il ne sera pas traités comme des volatiles dans le champ d'application de la fonction. Il y a des exceptions pour cela, comme lors de l'appel d'un interloqué de l'API.
fondamentalement, l'avertissement est que lorsque vous passez un champ volatile par référence, le code appelant ne sait pas le traiter d'une manière volatile. Pour Interloqué.Incrément qui n'a probablement pas d'importance, en raison de la nature de la méthode - mais alors vous n'avez pas besoin que la variable soit volatile de toute façon si vous utilisez Interlocked.
en général, je pense que j'éviterais de mélanger les deux - si vous utilisez entrelacés, le faire partout (en utilisant Interlocked.CompareExchange(ref counter, 0, 0)
pour le lire). Je ne peux pas dire que j'utilise volatile très souvent, personnellement. Pour les compteurs simples I pourrait utiliser enclenché, mais je suis plus susceptible d'utiliser un verrou pour la plupart des tâches.
utilisez ceci:
#pragma warning disable 420
// M
// dM
// MMr
// 4MMML .
// MMMMM. xf
// . "MMMMM .MM-
// Mh.. +MMMMMM .MMMM
// .MMM. .MMMMML. MMMMMh
// )MMMh. MMMMMM MMMMMMM
// 3MMMMx. 'MMMMMMf xnMMMMMM"
// '*MMMMM MMMMMM. nMMMMMMP"
// *MMMMMx "MMMMM\ .MMMMMMM=
// *MMMMMh "MMMMM" JMMMMMMP
// MMMMMM 3MMMM. dMMMMMM .
// MMMMMM "MMMM .MMMMM( .nnMP"
// =.. *MMMMx MMM" dMMMM" .nnMMMMM*
// "MMn... 'MMMMr 'MM MMM" .nMMMMMMM*"
// "4MMMMnn.. *MMM MM MMP" .dMMMMMMM""
// ^MMMMMMMMx. *ML "M .M* .MMMMMM**"
// *PMMMMMMhn. *x > M .MMMM**""
// ""**MMMMhx/.h/ .=*"
// .3P"%....
// nP" "*MMnx
if(Interlocked.CompareExchange(ref isLoaded, 1, 0) != 0)
return;
#pragma warning restore 420
vous obtenez l'erreur parce que vous passez le champ par référence. Je pense que cela signifie que la méthode cible n'a aucune idée que le champ est marqué volatile
, et donc ne le traitera pas comme tel.