“对易失性字段的引用不会被视为易变的”影响
下面的代码
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"
我在这里做错了什么来提出这个警告? 为什么编译器会提醒我呢?
你没有做错什么。 根据文件 :
一个volatile字段通常不应该使用ref或outparameter passing,因为在函数范围内它不会被视为volatile。 有一些例外情况,例如在调用互锁API时。
基本上警告的是,当你通过引用传递一个易失性字段时,调用代码不知道以易变的方式处理它。 对于Interlocked.Increment而言,由于方法的性质,可能无关紧要,但是如果使用Interlocked ,则无需使用variables即可。
一般来说,我想避免混淆两者 – 如果你使用Interlocked,那么到处都是 (使用Interlocked.CompareExchange(ref counter, 0, 0)
来读取它)。 我不能说我个人经常使用volatile。 对于简单的计数器我可能会使用联锁,但是我更可能使用锁来完成大部分任务。
用这个:
#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
,因此不会这样对待。