& # 8220; Une référence à un champ volatile ne sera pas traitée comme une source volatile & # 8221; implications

StackOverflow https://stackoverflow.com/questions/425132

Question

Le code suivant

using System.Threading;

class Test
{
    volatile int counter = 0;
    public void Increment()
    {
        Interlocked.Increment(ref counter);
    }
}

Lève l'avertissement du 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 lancer cet avertissement? Pourquoi le compilateur me prévient-il à ce sujet?

Était-ce utile?

La solution

Vous ne faites rien de mal. Selon la documentation :

  

Un champ volatile ne devrait normalement pas   être passé en utilisant un ref ou out   paramètre, car il ne sera pas   traité comme volatile dans le champ d'application   de la fonction. Il y a des exceptions   à cela, comme lorsque vous appelez un   API interverrouillée.

Autres conseils

En gros, l’avertissement est que, lorsque vous transmettez un champ volatile par référence, le code appelant ne sait pas le traiter de manière volatile. Pour Interlocked.Increment, cela n'a probablement aucune importance en raison de la nature de la méthode - mais dans ce cas, vous n'avez pas besoin que la variable soit volatile de toute façon si vous utilisez Interlocked.

En général, j’éviterais de mélanger les deux. Si vous utilisez Interlocked, faites-le partout (utilisez Interlocked.CompareExchange (ref counter, 0, 0) pour le lire). Je ne peux pas dire que j'utilise très souvent volatile, personnellement. Pour les compteurs simples, je pourrais utiliser Interlocked, 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. Cela signifie que la méthode cible n'a aucune idée que le champ est marqué comme volatile et ne le traitera donc pas comme tel.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top