ここには多くの質問があります。それらを1つずつ検討する:
参照割り当てはアトミックなので、なぜInterlocked.Exchange(ref Object、Object)が必要なのですか?
参照の割り当てはアトミックです。Interlocked.Exchangeは参照割り当てだけを行うわけではありません。変数の現在の値を読み取り、古い値を隠し、新しい値を変数に割り当てます。これらはすべてアトミック操作として行われます。
私の同僚は、一部のプラットフォームでは参照割り当てがアトミックであることが保証されていないことを言った。私の同僚は正しいですか?
いいえ。参照の割り当ては、すべての.NETプラットフォームでアトミックであることが保証されています。
私の同僚は誤った前提から推論しています。それは彼らの結論が間違っていることを意味しますか?
必ずしも。あなたの同僚は悪い理由であなたに良いアドバイスを与えているかもしれません。おそらく、Interlocked.Exchangeを使用する必要がある他の理由がいくつかあります。ロックフリーのプログラミングは非常に困難であり、あなたがフィールドの専門家によって支持されている確立された慣習から出発した瞬間、あなたは雑草にのっており、最悪の種類の競争状態の危険を冒しています。私はこの分野の専門家でも、あなたのコードの専門家でもないので、どちらにしても判断を下すことはできません。
「揮発性フィールドへの参照は揮発性として扱われません」という警告が表示されますこれについて何を考えればよいですか?
これが一般的に問題である理由を理解する必要があります。これにより、この特定のケースで警告が重要でない理由が理解されます。
コンパイラがこの警告を表示する理由は、フィールドを揮発性としてマークすることは、「このフィールドは複数のスレッドで更新されることになる」という意味です。このフィールドの値をキャッシュするコードを生成せず、このフィールドは、プロセッサキャッシュの不整合によって「時間的に前後に移動」されません。」
(私はあなたがすべてをすでに理解していると思います。揮発性の意味とそれがプロセッサキャッシュのセマンティクスにどのように影響するかについての詳細な理解がない場合、それがどのように機能するか理解できず、揮発性を使用すべきではありません。ロックフリープログラム正しく理解するのは非常に困難です。誤ってではなく、プログラムの仕組みを理解しているため、プログラムが正しいことを確認してください。
次に、揮発性フィールドにrefを渡して、そのフィールドのエイリアスである変数を作成するとします。呼び出されたメソッドの内部では、コンパイラは参照が揮発性のセマンティクスを持つ必要があることを知る理由がまったくありません!コンパイラーは、揮発性フィールドのルールの実装に失敗したメソッドのコードを陽気に生成しますが、変数は揮発性フィールドです。これはロックフリーのロジックを完全に破壊する可能性があります。仮定は、揮発性のフィールドがされていることを常に常に揮発性セマンティクスを使用してアクセス。それをときどき揮発性として扱い、それ以外の場合ではないことは意味がありません。あなたはする必要があり、常にそうでなければ、他のアクセスに一貫性を保証することはできません一貫しています。
したがって、慎重に開発されたロックフリーロジックを完全に混乱させる可能性があるため、これを行うとコンパイラーは警告を出します。
もちろん、Interlocked.Exchange は、揮発性フィールドを期待して正しいことを行うように作成されています。したがって、警告は誤解を招くものです。私はこれを非常に後悔しています。Interlocked.Exchangeなどのメソッドの作成者が「refを受け取るこのメソッドは変数に揮発性のセマンティクスを適用するため、警告を抑制します」と言ってメソッドに属性を設定できるメカニズムを実装する必要があります。おそらく、コンパイラの将来のバージョンでそうするでしょう。