43

次のコード

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"

この警告を発するために、ここで何か間違ったことをしていますか? コンパイラ me がこれについて警告するのはなぜですか?

4

4 に答える 4

46

あなたは何も悪いことをしていません。ドキュメントによると:

volatile フィールドは、関数のスコープ内で volatile として扱われないため、通常、ref または out パラメータを使用して渡されるべきではありません。連動 API を呼び出す場合など、これには例外があります。

于 2009-01-08T17:29:20.837 に答える
34

基本的に、参照によって揮発性フィールドを渡すと、呼び出し元のコードはそれを揮発性の方法で処理することを知らないという警告があります。Interlocked.Increment の場合、メソッドの性質上、おそらく問題にはなりませんが、Interlocked を使用している場合は、とにかく変数を揮発性にする必要はありません。

一般に、私はこの 2 つを混在させることは避けたいと思います。Interlocked を使用している場合は、どこでも(Interlocked.CompareExchange(ref counter, 0, 0)読み取りに使用して) 実行してください。個人的には、volatile を頻繁に使用するとは言えません。単純なカウンターには Interlocked を使用するかもしれませんが、ほとんどのタスクではロックを使用する可能性が高くなります。

于 2009-01-08T17:28:47.077 に答える
3

フィールドを参照渡ししているため、エラーが発生しています。volatileこれが意味することは、ターゲットメソッドはフィールドが としてマークされていることを認識していないため、そのように扱わないということだと思います。

于 2009-01-08T17:28:09.950 に答える