«Ссылка на изменчивое поле не будет рассматриваться как изменчивая» - PullRequest
42 голосов
/ 08 января 2009

следующий код

using System.Threading;

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

Выдает следующее предупреждение компилятора:

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

Я что-то не так делаю, чтобы поднять это предупреждение? Почему компилятор меня предупреждает об этом?

Ответы [ 4 ]

44 голосов
/ 08 января 2009

Вы не делаете ничего плохого. Согласно документации :

Летучее поле обычно не должно быть переданы с использованием ссылки или из параметр, так как его не будет рассматривается как изменчивый в объеме функции. Есть исключения к этому, например, при вызове заблокированный API.

30 голосов
/ 08 января 2009

По сути, предупреждение заключается в том, что когда вы передаете изменяемое поле по ссылке, вызывающий код не знает, как обработать его изменяемым образом. Для Interlocked.Increment это, вероятно, не имеет значения из-за характера метода - но тогда вам не нужно, чтобы переменная была изменчивой в любом случае , если вы используете Interlocked.

В общем, я думаю, что я бы избегал смешивания двух - если вы используете Interlocked, делайте это везде (используйте Interlocked.CompareExchange(ref counter, 0, 0) для чтения). Я не могу сказать, что я использую volatile очень часто, лично. Для простых счетчиков я может использовать Interlocked, но я чаще использую блокировку для большинства задач.

29 голосов
/ 03 октября 2009

Используйте это:

        #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
3 голосов
/ 08 января 2009

Вы получаете ошибку, потому что вы передаете поле по ссылке. Я думаю, что это означает, что целевой метод не знает, что поле помечено как volatile, и поэтому не будет рассматривать его как таковое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...