lock (new object ()) - Kargo kültü mü yoksa çılgın bir "dil özel durumu" mu?


87

Bir danışman tarafından yazılan bazı kodları gözden geçiriyorum ve düzinelerce kırmızı bayrak çoktan ortaya çıkmış olsa da, kafamı şu kod parçacığına dolayamıyorum:

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 ()) burada ne yapıyor? Her zaman başka bir nesneye kilitlendiği için herhangi bir etkisi olmamalıdır, ancak bu tür bir kilitleme, kopyala-yapıştır olmayan bölümlerde bile kod boyunca kalıcıdır. Bu C # dilinde bilmediğim bir şeye derlenen özel bir durum mu yoksa programcı bir süre önce işe yarayan bir kargo kültünü mi benimsedi?


19
Sanırım kafaları çok karışık. Muhtemelen new object()bir tarlada saklandığını ve bu alanın lock()ifadelerde kullanıldığını gördüler ve onu satır içine almamayı daha iyi bilmiyorlardı.
Damien_The_Unbeliever

21
O "danışmanın" yapması gereken bazı açıklamalar var ... yanılıyorsunuz: bu lockkod tamamen işe yaramaz
Marc Gravell

12
@Baboon: Yalnızca yeniden düzenleme yapmak zorunda olan siz değilseniz ...

2
Artı, eğer bu WinForms ise, neden orada bir kilit olması gerektiğini anlayamıyorum.
Drew Noakes

7
Bunu kaldırın, ardından% 100 kod kapsamı test paketinizi yeniden çalıştırın. Bu da ne? Önceki danışman yapmadı mı?
Spacedman

Yanıtlar:


82

Bunu gören biri olsaydı şaşırmazdım:

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

ve satır sayısını azaltabileceğini düşündü.

Yine de durum böyle olsaydı çok endişelenirdim ...


4
"NewObject ()" adlı bir yöntem görmüş olabilir ve bu yöntem bir tekil örnek döndürdü, ancak "hey, c # bunun için anahtar kelimelere sahip değil" dedi?
Amiram Korach

9
Gerçekten de, neler olup bittiğini etkili bir şekilde anlamadan bir yeniden düzenleme işi gibi görünüyor.
Afeliyon

1
@OrangeDog: Maalesef bu imkansız, çünkü ilgili kod şirkete katılmadan önce yazılmıştı. Artık yapılacak değişiklikler olduğuna göre, belki yönetimi kodu düzeltmeme izin vermeye ikna edebilirim. Aksi takdirde herhangi bir kararsızlığın sorumluluğunu üstlenmeyeceğim (herhangi bir şeye dokunan son kişi suçlanacak

2
@Ibruder Yüksek öncelik, Yönetimi sürüm kontrolüne, otomatik testlere ve gözden geçirme sistemlerine ihtiyaç duyduklarına ikna etmek olacaktır. Bir şeye en son dokunan kişi suçlanacaksa, o zaman çalışmak için çok iyi bir şirket gibi görünmüyor.
OrangeDog

1
Açıkça kırılmış kilitleme umrumda değil - diğer herkes bunu zaten belirtti, ancak 'veya iOS öncesi 4/5' <g> programları için +1
Martin James

15

İşte benzer soru ve cevap:

Kilitler, karşılıklı dışlamayı garanti eder - aynı anda birden fazla iplik kilidi tutamaz. Kilit, belirli bir nesne örneğiyle tanımlanır. Her seferinde kilitlenecek yeni bir nesne oluşturuyorsunuz ve aynı nesne örneğine kilitlenmeleri için başka hiçbir iş parçacığına bilgi vermenin bir yolu yok. Bu nedenle, kilitlemeniz işe yaramaz.


2

Muhtemelen işe yaramaz. Ancak bir hafıza engeli yaratmak için orada olma şansı var. C # 'nin kilit seçip seçmediğinden veya kilidin sıralama anlamını koruyup korumadığından emin değilim.


Birkaç yıl önceydi ama adamım, bazı insanların tamamen görmezden geldiği bu açık gerçeği belirttiğiniz için + 1'i kesinlikle hak ediyorsunuz. Örneğin, Evrensel Windows Platformunda MemoryBarrier () yöntemi yoktur ve Interlocked.CompareExchange ile sihir ve kilit (yeni Object ()) bazı sorunlarla başa çıkmanın tek yolu haline gelir.
Sergey.quixoticaxis.Ivanov

C # 'ın buna izin verdiğini bile bilmiyordum. Bunu belirtmen çok güzel.
herkes
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.