私はスレッドセーフなメソッドを記述しようとしていますが、これは一度だけ(オブジェクトインスタンスごとに)呼び出すことができます。以前に呼び出された場合は、例外をスローする必要があります。方法:一度だけ呼び出すことができるスレッドセーフメソッドを記述しますか?
私は2つの解決策を考え出しました。彼らはどちらも正しいですか?そうでない場合、何が問題なのですか? lock
で
:
public void Foo() { lock (fooLock) { if (fooCalled) throw new InvalidOperationException(); fooCalled = true; } … } private object fooLock = new object(); private bool fooCalled;
Interlocked.CompareExchange
付:私は間違っていない場合は、このソリューションはロックフリーであるという利点を有する(public void Foo() { if (Interlocked.CompareExchange(ref fooCalled, 1, 0) == 1) throw new InvalidOperationException(); … } private int fooCalled;
私の場合は無関係と思われる)、それよりも少ないプライベートフィールド。
私はまた、どちらの解決策を優先すべきかについての正当な意見や、より良い方法があればさらに提案することができます。
好奇心を要しています。「あまり複雑ではない」と言えば、ブラインドの背後にあるすべてのものを指しているようです。あなたは平均的なプログラマーのための 'Interlocked.ExchangeCompare'構造の読みやすさ/理解の容易性をどのように判断しますか? – stakx
@stakx:これはコメントのためのものです。プログラマが理解できないことに遭遇すると、プログラマはそれを理解して理解するように見上げるべきです。それが彼らがより良いプログラマになる方法です。 – thecoop
@thecoop私はそれに反してはい、それは最も正しい解決策ですが、それは単純ではありません、あなたは原子操作などについて知る必要があります。これは何とか初期化プロセスであり、広く使用されている初期化パターンに従うことをお勧めしますチェックされたロック)。また、これらのパターンは、スレッドを実行するときに簡単に発生する可能性のあるものを逃してしまうのを防ぎます。 – ntziolis