"الإشارة إلى مجال متقلبة لن يتم التعامل معها على أنها متقلبة"

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

سؤال

الرمز التالي

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"

هل أفعل شيئًا خاطئًا هنا لرفع هذا التحذير؟ لماذا يحذرني المترجم من هذا؟

هل كانت مفيدة؟

المحلول

انك لم تفعل شيئا خاطئا. بحسب ال توثيق:

لا ينبغي عادة تمرير الحقل المتطاير باستخدام معلمة المرجع أو خارج ، لأنه لن يتم التعامل معه على أنه متقلبة في نطاق الوظيفة. هناك استثناءات لهذا ، مثل عند استدعاء واجهة برمجة التطبيقات المتشابكة.

نصائح أخرى

في الأساس التحذير هو أنه عندما تمر بحقل متقلبة بالرجوع إليه ، لا يعرف رمز الاتصال أن يعامله بطريقة متقلبة. بالنسبة إلى interlocked.increment هذا ربما لا يهم ، بسبب طبيعة الطريقة - ولكن بعد ذلك لا تحتاج إلى أن يكون المتغير متطوراً على أي حال إذا كنت تستخدم متشابك.

بشكل عام ، أعتقد أنني سأتجنب خلط الاثنين - إذا كنت تستخدم متشابكًا ، فافعل ذلك في كل مكان (استخدام Interlocked.CompareExchange(ref counter, 0, 0) لقراءته). لا أستطيع أن أقول إنني أستخدم متقلبة في كثير من الأحيان ، شخصيا. لعدادات بسيطة أنا قد استخدم متشابكًا ، لكنني أكثر عرضة لاستخدام قفل لمعظم المهام.

استخدم هذا:

        #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

أنت تحصل على الخطأ لأنك تمرير الحقل بالرجوع إليه. أعتقد أن ما يعنيه هذا هو أن الطريقة المستهدفة ليس لها فكرة أن الحقل محدد volatile, ، وبالتالي لن يعاملها على هذا النحو.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top