Здесь много вопросов. Рассматривая их по одному:
Ссылочное присвоение является атомарным, так зачем Interlocked.Exchange (ref Object, Object)?
Ссылочное присвоение является атомарным. Interlocked.Exchange не делает только ссылки. Он читает текущее значение переменной, скрывает старое значение и назначает новое значение переменной, все как атомарная операция.
мой коллега сказал, что на некоторых платформах не гарантируется, что задание ссылки является атомарным. Был ли мой коллега прав?
Нет. Назначение ссылок гарантированно будет атомарным на всех платформах .NET.
Мой коллега рассуждает из ложных посылок. Значит ли это, что их выводы неверны?
Не обязательно. Ваш коллега может дать вам хороший совет по плохим причинам. Возможно, есть какая-то другая причина, почему вы должны использовать Interlocked.Exchange. Программирование без блокировок безумно сложно, и в тот момент, когда вы отказываетесь от устоявшихся практик, поддерживаемых экспертами в этой области, вы теряете травку и рискуете наихудшими условиями гонки. Я не являюсь ни экспертом в этой области, ни экспертом в вашем коде, поэтому я не могу судить так или иначе.
выдает предупреждение "ссылка на изменчивое поле не будет рассматриваться как изменчивая" Что я должен думать об этом?
Вы должны понимать, почему это вообще проблема. Это приведет к пониманию того, почему предупреждение не имеет значения в данном конкретном случае.
Причина, по которой компилятор выдает это предупреждение, заключается в том, что пометка поля как энергозависимого означает, что «это поле будет обновляться в нескольких потоках - не генерируйте код, который кэширует значения этого поля, и убедитесь, что любое чтение или записи этого поля не "перемещаются вперед и назад во времени" из-за несогласованности кеша процессора ".
(Я предполагаю, что вы уже все это понимаете. Если у вас нет детального понимания значения volatile и его влияния на семантику кэша процессора, то вы не понимаете, как оно работает, и не должны использовать volatile. Lock - бесплатные программы очень сложно понять правильно, убедитесь, что ваша программа правильная, потому что вы понимаете, как она работает, а не случайно.)
Теперь предположим, что вы создаете переменную, которая является псевдонимом энергозависимого поля, передавая ссылку в это поле. Внутри вызываемого метода у компилятора нет никаких оснований знать, что ссылка должна иметь изменчивую семантику! Компилятор с радостью сгенерирует код для метода, который не может реализовать правила для изменчивых полей, но переменная является изменяемым полем. Это может полностью разрушить вашу логику без блокировки; всегда предполагается, что к летучему полю всегда обращаются с изменчивой семантикой. Нет смысла рассматривать это как изменчивое время от времени, а не другие времена; вы должны всегда быть последовательными, иначе вы не сможете гарантировать согласованность при других доступах.
Поэтому компилятор предупреждает, когда вы делаете это, потому что он, вероятно, полностью испортит вашу тщательно разработанную логику без блокировки.
Конечно, Interlocked.Exchange написан для ожидания изменчивого поля и правильного поведения. Поэтому предупреждение вводит в заблуждение. Я очень сожалею об этом; то, что мы должны были сделать, - это реализовать некоторый механизм, посредством которого автор метода, такого как Interlocked.Exchange, мог бы поместить в метод атрибут, говорящий: «этот метод, который принимает ссылку, применяет изменяемую семантику к переменной, поэтому подавьте предупреждение». Возможно, в следующей версии компилятора мы сделаем это.