lock(new object())—カーゴカルトまたはクレイジーな「言語の特殊なケース」?


87

コンサルタントによって作成されたコードを確認しています。すでに数十の危険信号が表示されていますが、次のスニペットに頭を悩ませることはできません。

private void foo()
{
    if (InvokeRequired)
    {
        lock (new object())
        {
            if (m_bar!= null)
                Invoke(new fooDelegate(foo), new object[] { });
        }
    }
    else
    {
        if(OnBazChanged != null)
            OnBazChanged();
    }
}

ここでlock(new object())は何をしていますか?常に別のオブジェクトをロックしているため、何の効果もありませんが、この種のロックは、コピーして貼り付けられていない部分であっても、コード全体で持続します。これは、私が知らないものにコンパイルされたC#言語の特殊なケースですか、それともプログラマーは、たまたま機能していたカーゴカルトを採用しただけですか?


19
彼らは非常に混乱していると思います。彼らはおそらく、new object()がフィールドに格納されている場所でそれを見て、そのフィールドがlock()ステートメントで使用されていたので、インライン化しないほうがよいとは知りませんでした。
damien_The_Unbeliever 2012

21
その「コンサルタント」には説明があります...あなたは間違っていません:そのlockコードは完全に役に立たない
MarcGravell

12
@Baboon:リファクタリングを行う必要があるのがあなたでない場合のみ...

2
さらに、これがWinFormsの場合、なぜそこにロックが必要なのかまったくわかりません。
ドリューノアケス2012

7
それを削除してから、100%コードカバレッジテストスイートを再実行します。あれは何でしょう?前のコンサルタントはそれを作りませんでしたか?
Spacedman 2012

回答:


82

これを見た人がいたとしても、私は驚かないでしょう。

private readonly object lockObj = new object();

private void MyMethod()
{
    lock(lockObj)
    {
        // do amazing stuff, so amazing it can only run once at a time
        // e.g. comands on the Mars Rover, or programs on iOS pre 4 / 5 ??
    }
}

そして彼は行数を減らすことができると思いました。

もしそうなら、私は非常に心配するでしょう...


4
彼は「newObject()」と呼ばれるメソッドを見て、このメソッドがシングルトンインスタンスを返したかもしれませんが、「ねえ、c#にはそのためのキーワードがありません」と言いましたか?
Amiram Korach 2012

9
何が起こっているのかを効果的に理解していないのは、確かにリファクタリングの仕事のように聞こえます。
遠地点

1
@OrangeDog:残念ながら、私が入社する前に関連するコードが書かれていたので、それは不可能です。変更が加えられたので、管理者にコードを修正させることができるかもしれません。それ以外の場合、私はいかなる不安定性についても責任を負いません(最後に何かに触れたのは責任のあるものです)...

2
@Ibruder優先度が高いのは、バージョン管理、自動テスト、およびレビューシステムが必要であることを経営陣に納得させることです。最後に何かに触れたのが責任者だとしたら、それは働きがいのある会社のようには思えません。
OrangeDog 2012

1
私は明らかに壊れたロックについてはあまり気にしません-他の誰もがすでにそれを指摘していますが、iOSの4/5以前のプログラムのためだけに+1します<g>
Martin James

15

ここで同様の質問、およびその答えは次のとおりです。

ロックは相互排除を保証します-同時にロックを保持できるスレッドは1つだけです。ロックは特定のオブジェクトインスタンスで識別されます。毎回ロックする新しいオブジェクトを作成していて、まったく同じオブジェクトインスタンスをロックするように他のスレッドに通知する方法がありません。したがって、ロックは役に立ちません。


2

おそらく役に立たないでしょう。しかし、メモリバリアを作成する可能性はほとんどありません。c#がロックの省略を行うのか、それともロックの順序付けのセマンティクスを保持するのかはわかりません。


数年前のことですが、一部の人が完全に無視しているというこの明らかな事実を述べると、あなたは完全に+1に値します。たとえば、ユニバーサルWindowsプラットフォームにはMemoryBarrier()メソッドがなく、Interlocked.CompareExchangeとlock(new Object())を使用した魔法がいくつかの問題に対処する唯一の方法になります。
sergey.quixoticaxis.Ivanov 2016

C#でこれが許可されていることすら知りませんでした。それを指摘してくれてありがとう。
全員
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.