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