lock (neues Objekt ()) - Frachtkult oder ein verrückter „Sprach-Sonderfall“?

87

Ich überprüfe einen Code, der von einem Berater geschrieben wurde, und obwohl bereits Dutzende roter Fahnen aufgetaucht sind, kann ich mich nicht um das folgende Snippet kümmern:

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

Was macht lock (new object ()) hier? Sollte keinerlei Auswirkungen haben, da immer ein anderes Objekt gesperrt wird. Diese Art der Sperre bleibt jedoch im gesamten Code bestehen, auch in nicht kopierten und eingefügten Teilen. Ist dies ein Sonderfall in der C # -Sprache, der zu etwas kompiliert wurde, von dem ich nichts weiß, oder hat der Programmierer einfach einen Frachtkult übernommen, der vor einiger Zeit funktioniert hat?

Charles
quelle
19
Ich denke, sie sind sehr verwirrt. Sie haben es wahrscheinlich gesehen, wo das new object()in einem Feld gespeichert war, und dieses Feld wurde in den lock()Anweisungen verwendet, und sie wussten nicht besser, es nicht zu inlineieren.
Damien_The_Unbeliever
21
Dieser "Berater" muss einige Erklärungen lock
abgeben
12
@ Baboon: Nur wenn Sie nicht derjenige sind, der das Refactoring durchführen muss ...
2
Wenn dies WinForms ist, kann ich nicht sehen, warum dort überhaupt eine Sperre vorhanden sein sollte.
Drew Noakes
7
Entfernen Sie es und führen Sie Ihre 100% Code-Coverage-Testsuite erneut aus. Was ist das? Der vorherige Berater hat keinen gemacht?
Spacedman

Antworten:

82

Ich wäre nicht überrascht, wenn jemand dies gesehen hätte:

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 ??
    }
}

und dachte, er könnte die Anzahl der Zeilen reduzieren.

Ich wäre sehr besorgt, wenn das der Fall wäre ...

cjk
quelle
4
Er könnte eine Methode namens "newObject ()" gesehen haben und diese Methode hat eine Singleton-Instanz zurückgegeben, aber er sagte "hey, hat c # keine Schlüsselwörter dafür"?
Amiram Korach
9
Es klingt in der Tat wie ein Refactoring-Job, ohne effektiv zu verstehen, was los war.
Aphelion
1
@OrangeDog: Leider ist das unmöglich, da der betreffende Code geschrieben wurde, bevor ich zur Firma kam. Jetzt, da Änderungen vorgenommen werden müssen, kann ich das Management möglicherweise davon überzeugen, den Code reparieren zu lassen. Andernfalls übernehme ich keine Verantwortung für Instabilitäten (der letzte, der etwas berührt, ist der Schuldige) ...
2
@Ibruder Höhere Priorität wäre es, das Management davon zu überzeugen, dass Versionskontrolle, automatisierte Test- und Überprüfungssysteme erforderlich sind. Wenn der letzte, der etwas berührt, derjenige ist, der die Schuld trägt, dann klingt es nicht nach einer sehr guten Firma, für die man arbeitet.
OrangeDog
1
Ich kümmere mich nicht viel um die offensichtlich kaputte Verriegelung - alle anderen haben bereits darauf hingewiesen, aber +1 nur für 'oder Programme unter iOS vor 4/5' <g>
Martin James
15

Hier ist eine ähnliche Frage und Antwort:

Sperren gewährleisten den gegenseitigen Ausschluss - nicht mehr als ein Thread darf die Sperre gleichzeitig halten. Die Sperre wird mit einer bestimmten Objektinstanz identifiziert. Sie erstellen jedes Mal ein neues Objekt, das gesperrt werden soll, und Sie haben keine Möglichkeit, einen anderen Thread zu informieren, der genau dieselbe Objektinstanz sperren soll. Daher ist Ihre Verriegelung unbrauchbar.

JleruOHeP
quelle
2

Es ist wahrscheinlich nutzlos. Es besteht jedoch die Möglichkeit, dass eine Speicherbarriere entsteht. Nicht sicher, ob c # die Elision sperrt oder ob die Ordnungssemantik der Sperre beibehalten wird.

benmmurphy
quelle
Es war vor ein paar Jahren, aber Mann, Sie haben absolut +1 verdient, weil Sie diese offensichtliche Tatsache angegeben haben, die einige Leute völlig ignoriert haben. Auf der universellen Windows-Plattform gibt es beispielsweise keine MemoryBarrier () -Methode und keine Magie mit Interlocked.CompareExchange und lock (new Object ()) sind die einzigen Möglichkeiten, um einige Probleme zu lösen.
Sergey.quixoticaxis.Ivanov
Ich wusste nicht einmal, dass C # das erlaubt. Schön, dass Sie darauf hinweisen.
Jeder