lock (new object ()) - Kult Cargo czy jakiś zwariowany „specjalny przypadek językowy”?

87

Przeglądam kod napisany przez konsultanta i chociaż pojawiły się już dziesiątki czerwonych flag, nie mogę otoczyć głowy następującym fragmentem:

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

Co tu robi lock (new object ())? Nie powinno mieć żadnego efektu, ponieważ zawsze blokuje inny obiekt, ale ten rodzaj blokowania jest trwały w całym kodzie, nawet w częściach, które nie są kopiowane i wklejane. Czy jest to jakiś szczególny przypadek w języku C #, który jest skompilowany do czegoś, o czym nie wiem, czy też programista po prostu przyjął jakiś kult cargo, który działał jakiś czas temu?

Charles
źródło
19
Myślę, że są bardzo zdezorientowani. Prawdopodobnie widzieli to, gdy new object()był przechowywany w polu, a to pole było używane w lock()wyciągach, i nie wiedzieli lepiej, aby go nie wstawiać.
Damien_The_Unbeliever,
21
Ten „konsultant” musi coś wytłumaczyć ... nie mylisz się: ten lockkod jest całkowicie bezużyteczny
Marc Gravell
12
@Baboon: Tylko jeśli nie jesteś tym, który musi przeprowadzić refaktoryzację ...
2
Poza tym, jeśli to są WinForms, nie rozumiem, dlaczego w ogóle ma tam być blokada.
Drew Noakes
7
Usuń go, a następnie ponownie uruchom pakiet testów 100% pokrycia kodu. Co to jest? Poprzedni konsultant go nie zrobił?
Spacedman

Odpowiedzi:

82

Nie zdziwiłbym się, gdyby to był ktoś, kto to widział:

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

i pomyślał, że mógłby zmniejszyć liczbę linii.

Byłbym bardzo zmartwiony, gdyby tak było ...

cjk
źródło
4
Mógł zobaczyć metodę o nazwie „newObject ()”, która zwróciła pojedynczą instancję, ale powiedział „hej, czy c # nie ma na to słów kluczowych”?
Amiram Korach,
9
Rzeczywiście brzmi to jak praca na refaktoryzacji bez skutecznego zrozumienia, co się dzieje.
Aphelion
1
@OrangeDog: Niestety jest to niemożliwe, ponieważ kod, o którym mowa, został napisany zanim dołączyłem do firmy. Teraz, gdy są zmiany do wprowadzenia, być może uda mi się przekonać zarząd, aby pozwolił mi naprawić kod. W przeciwnym razie nie wezmę odpowiedzialności za jakiekolwiek niestabilności (winna jest ostatnia osoba, która czegokolwiek dotknie) ...
2
@Ibruder Wyższym priorytetem byłoby przekonanie kierownictwa, że ​​potrzebują kontroli wersji, zautomatyzowanych testów i systemów przeglądów. Jeśli winna jest ostatnia osoba, która czegokolwiek dotknie, to nie wygląda na to, że warto pracować dla bardzo dobrej firmy.
OrangeDog
1
Nie dbam zbytnio o oczywiście złamane ryglowania - wszyscy już zwrócił na to uwagę, ale tylko do +1 „lub programy na iOS pre 4/5” <g>
Martin James
15

Oto podobne pytanie i odpowiedź:

Zamki zapewniają wzajemne wykluczanie - nie więcej niż jeden nić może jednocześnie przytrzymywać zamek. Blokada jest identyfikowana za pomocą określonej instancji obiektu. Tworzysz nowy obiekt do zablokowania za każdym razem i nie masz żadnego sposobu, aby poinformować żaden inny wątek, aby zablokował dokładnie tę samą instancję obiektu. Dlatego twoje blokowanie jest bezużyteczne.

JleruOHeP
źródło
2

Prawdopodobnie jest bezużyteczna. Ale istnieje szansa, że ​​stworzy barierę pamięci. Nie jestem pewien, czy C # wykonuje blokadę lub czy robi, czy zachowuje porządkowanie semantyki blokady.

benmmurphy
źródło
To było kilka lat temu, ale człowieku, całkowicie zasługujesz na +1 za stwierdzenie tego oczywistego faktu, który niektórzy ludzie całkowicie ignorowali. Na przykład na Universal Windows Platform nie ma metody MemoryBarrier (), a magia z Interlocked.CompareExchange i lock (new Object ()) stają się jedynymi sposobami rozwiązania niektórych problemów.
Sergey.quixoticaxis.Ivanov
Nawet nie wiedziałem, że C # na to pozwala. Świetnie, że zwróciłaś uwagę.
Wszyscy