“A reference to a volatile field will not be treated as volatile” implications

前端 未结 4 1426
慢半拍i
慢半拍i 2020-12-02 15:52

The following code

using System.Threading;

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


        
相关标签:
4条回答
  • 2020-12-02 16:01

    You are not doing anything wrong. According to the documentation:

    A volatile field should not normally be passed using a ref or out parameter, since it will not be treated as volatile within the scope of the function. There are exceptions to this, such as when calling an interlocked API.

    0 讨论(0)
  • 2020-12-02 16:02

    Basically the warning is that when you pass a volatile field by reference, the calling code doesn't know to treat it in a volatile manner. For Interlocked.Increment that probably doesn't matter, due to the nature of the method - but then you don't need the variable to be volatile anyway if you're using Interlocked.

    In general, I think I'd avoid mixing the two - if you're using Interlocked, do it everywhere (using Interlocked.CompareExchange(ref counter, 0, 0) to read it). I can't say I use volatile very often, personally. For simple counters I might use Interlocked, but I'm more likely to use a lock for most tasks.

    0 讨论(0)
  • 2020-12-02 16:04

    You're getting the error because you're passing the field by reference. I think what this means is that the target method has no idea the field is marked as volatile, and therefore will not treat it as such.

    0 讨论(0)
  • 2020-12-02 16:10

    Use this:

            #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
    
    0 讨论(0)
提交回复
热议问题