Pregunta

El siguiente código

using System.Threading;

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

Genera la siguiente advertencia del compilador:

"A reference to a volatile field will not be treated as volatile"

¿Estoy haciendo algo mal aquí para generar esta advertencia? ¿Por qué el compilador me advierte sobre esto?

¿Fue útil?

Solución

No estás haciendo nada malo. De acuerdo con la documentación :

  

Un campo volátil no debería normalmente   ser aprobado usando una referencia o fuera   parámetro, ya que no será   tratado como volátil dentro del alcance   de la función. Hay excepciones   a esto, como cuando se llama a un   API entrelazada.

Otros consejos

Básicamente, la advertencia es que cuando pasa un campo volátil por referencia, el código de llamada no sabe tratarlo de manera volátil. Para Interlocked. Incremento que probablemente no importa, debido a la naturaleza del método, pero entonces no necesita que la variable sea volátil de todos modos si usa Interlocked.

En general, creo que evitaría mezclar los dos: si usa Interlocked, hágalo everywhere (utilizando Interlocked.CompareExchange (ref counter, 0, 0) para leerlo). No puedo decir que uso volatile muy a menudo, personalmente. Para contadores simples, podría usar Interbloqueado, pero es más probable que use un bloqueo para la mayoría de las tareas.

Use esto:

        #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

Obtiene el error porque pasa el campo por referencia. Creo que lo que esto significa es que el método de destino no tiene idea de que el campo esté marcado como volatile y, por lo tanto, no lo tratará como tal.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top