Domanda

Il seguente codice

using System.Threading;

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

Genera il seguente avviso del compilatore:

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

Sto facendo qualcosa di sbagliato qui per sollevare questo avviso? Perché il compilatore mi avvisa di questo?

È stato utile?

Soluzione

Non stai facendo nulla di male. Secondo la documentazione :

  

Un campo volatile non dovrebbe normalmente   essere passato usando un ref o out   parametro, poiché non lo sarà   trattato come volatile nell'ambito   della funzione. Ci sono eccezioni   a questo, come quando si chiama un   API interbloccata.

Altri suggerimenti

Fondamentalmente l'avvertimento è che quando si passa un campo volatile per riferimento, il codice chiamante non sa come trattarlo in modo volatile. Per Interlocked.Increment che probabilmente non ha importanza, a causa della natura del metodo, ma non è necessario che la variabile sia volatile comunque se si utilizza Interlocked.

In generale, penso che eviterei di mescolare i due: se stai usando Interlocked, fallo ovunque (usando Interlocked.CompareExchange (ref counter, 0, 0) per leggerlo). Non posso dire di usare volatile molto spesso, personalmente. Per i contatori semplici, potrei utilizzare Interbloccato, ma ho maggiori probabilità di utilizzare un blocco per la maggior parte delle attività.

Usa questo:

        #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

Stai ricevendo l'errore perché stai passando il campo per riferimento. Penso che ciò significhi che il metodo target non ha idea che il campo sia contrassegnato come volatile , e quindi non lo tratterà come tale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top