"Ссылка на нестабильное поле не будет рассматриваться как изменчивые" последствия
Следующий код
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"
Я делаю что-то неправильно здесь, чтобы поднять это предупреждение? Почему компилятор мне предупреждает об этом?
Ответы
Ответ 1
Ты не делаешь ничего плохого. Согласно документации:
Нестабильное поле обычно не должно передаваться с использованием ref или out параметр, поскольку он не будет рассматривается как изменчивый в рамках функции. Есть исключения к этому, например, при вызове взаимосвязанный API.
Ответ 2
В основном предупреждение состоит в том, что когда вы передаете поле volatile по ссылке, вызывающий код не знает, чтобы обрабатывать его волатильным образом. Для Interlocked.Increment, который, вероятно, не имеет значения, из-за характера метода, - но тогда вам не нужна переменная, чтобы быть изменчивой в любом случае, если вы используете Interlocked.
В общем, я думаю, что я бы не стал смешивать два - если вы используете Interlocked, делайте это везде (используя Interlocked.CompareExchange(ref counter, 0, 0)
для его чтения). Я не могу сказать, что я часто использую изменчивость, лично. Для простых счетчиков я могу использовать Interlocked, но я скорее всего использую блокировку для большинства задач.
Ответ 3
Используйте это:
#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
Ответ 4
Вы получаете ошибку, потому что вы передаете поле по ссылке. Я думаю, что это означает, что целевой метод не имеет понятия, что поле отмечено как volatile
, и поэтому не будет рассматривать его как таковое.