“对volatile字段的引用不会被视为volatile”启示
-
06-07-2019 - |
题
以下代码
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"
我在这里做错了什么来提出这个警告?为什么编译器会对此发出警告?
解决方案
你没有做错任何事。根据文档:
挥发性字段通常不应该 使用ref或out传递 参数,因为它不会 在范围内被视为易变 功能。也有例外 对此,例如在打电话时 互锁API。
其他提示
基本上警告是,当您通过引用传递volatile字段时,调用代码不知道以易失性方式处理它。对于可能无关紧要的Interlocked.Increment,由于方法的性质 - 但是如果你使用Interlocked,那么你不需要变量是无论如何 。
一般情况下,我认为我会避免混淆两者 - 如果您使用的是Interlocked,那么无处不在(使用 Interlocked.CompareExchange(ref counter,0,0)
来读它)。我不能说我个人经常使用volatile。对于简单的计数器,我可能使用Interlocked,但我更有可能使用锁来执行大多数任务。
使用此:
#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
,因此不会将其视为这样。
不隶属于 StackOverflow