lock (new object ()) - Cargo cult o qualche folle “language special case”?


87

Sto rivedendo del codice scritto da un consulente e, sebbene siano già spuntate dozzine di bandiere rosse, non riesco a capire il seguente frammento:

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

Cosa ci fa lock (new object ()) qui? Non dovrebbe avere alcun effetto in quanto si blocca sempre su un altro oggetto, ma questo tipo di blocco è persistente in tutto il codice, anche nelle parti non copiate e incollate. È un caso speciale nel linguaggio C # compilato su qualcosa che non conosco, o il programmatore ha semplicemente adottato un culto del carico che è capitato di funzionare qualche tempo fa?


19
Penso che siano molto confusi. Probabilmente l'hanno visto dove new object()era memorizzato in un campo, e quel campo è stato utilizzato nelle lock()dichiarazioni, e non sapevano meglio non metterlo in linea.
Damien_The_Unbeliever

21
Quel "consulente" ha delle spiegazioni da fare ... non ti sbagli: quel lockcodice è del tutto inutile
Marc Gravell

12
@ Baboon: Solo se non sei tu quello che deve fare il refactoring ...

2
Inoltre, se questo è WinForms, non riesco a capire perché dovrebbe esserci un lucchetto lì.
Drew Noakes

7
Rimuovilo, quindi esegui nuovamente la suite di test con copertura del codice al 100%. Cos'è quello? Il consulente precedente non ne ha fatto uno?
Spacedman

Risposte:


82

Non sarei sorpreso se fosse qualcuno che ha visto questo:

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

e pensava di poter ridurre il numero di righe.

Sarei molto preoccupato se fosse così però ...


4
Potrebbe vedere un metodo chiamato "newObject ()" e questo metodo ha restituito un'istanza singleton, ma ha detto "ehi, c # non ha parole chiave per questo"?
Amiram Korach

9
Sembra davvero un lavoro di refactoring senza capire effettivamente cosa stava succedendo.
Aphelion

1
@OrangeDog: Purtroppo è impossibile, poiché il codice in questione è stato scritto prima che entrassi in azienda. Ora che ci sono modifiche da apportare, forse posso convincere la direzione a lasciarmi correggere il codice. Altrimenti non mi

2
@Ibruder La priorità più alta sarebbe convincere la direzione della necessità di sistemi di controllo della versione, test automatizzati e revisione. Se la colpa è dell'ultimo a toccare qualcosa, allora non sembra una buona compagnia per cui lavorare.
OrangeDog

1
Non mi interessa molto il blocco ovviamente rotto - tutti gli altri lo hanno già fatto notare, ma +1 solo per "o programmi su iOS pre 4/5" <g>
Martin James

15

Ecco una domanda simile e risposta:

I blocchi garantiscono l'esclusione reciproca: non più di un thread può contenere il blocco contemporaneamente. Il blocco viene identificato con un'istanza di oggetto specifica. Stai creando un nuovo oggetto da bloccare ogni volta e non hai alcun modo per informare nessun altro thread di bloccarsi sulla stessa identica istanza dell'oggetto. Pertanto, il tuo blocco è inutile.


2

Probabilmente è inutile. Ma c'è la possibilità che sia lì per creare una barriera di memoria. Non sono sicuro se c # blocchi l'elisione o se lo fa se conserva la semantica di ordinamento del blocco.


È stato qualche anno fa, ma amico, ti meriti totalmente +1 per aver affermato questo fatto ovvio che alcune persone hanno completamente ignorato. Ad esempio, su Universal Windows Platform non esiste il metodo MemoryBarrier () e la magia con Interlocked.CompareExchange e lock (new Object ()) diventano gli unici modi per affrontare alcuni problemi.
Sergey.quixoticaxis.Ivanov

Non sapevo nemmeno che C # lo permettesse. Fantastico da parte tua farlo notare.
Tutti il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.