kunci (objek baru ()) - Kultus kargo atau "kasus khusus bahasa" gila?

87

Saya meninjau beberapa kode yang ditulis oleh seorang konsultan, dan sementara lusinan tanda bahaya telah muncul, saya tidak dapat memahami cuplikan berikut:

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

Apa yang dilakukan kunci (objek baru ()) di sini? Seharusnya tidak berpengaruh apa pun karena selalu mengunci objek lain, tetapi jenis penguncian ini tetap ada di seluruh kode, bahkan di bagian yang tidak disalin dan ditempel. Apakah ini kasus khusus dalam bahasa C # yang dikompilasi menjadi sesuatu yang tidak saya ketahui, atau apakah pemrogram hanya mengadopsi beberapa kultus kargo yang kebetulan berfungsi beberapa waktu lalu?

Charles
sumber
19
Saya pikir mereka sangat bingung. Mereka mungkin melihatnya di mana new object()disimpan di bidang, dan bidang itu digunakan dalam lock()pernyataan, dan mereka tidak tahu lebih baik untuk tidak menyebarnya.
Damien_The_Unbeliever
21
"Konsultan" itu memiliki beberapa penjelasan yang harus dilakukan ... Anda tidak salah: lockkode itu sama sekali tidak berguna
Marc Gravell
12
@Baboon: Hanya jika Anda bukan orang yang harus melakukan refactoring ...
2
Plus, jika ini adalah WinForms, maka saya tidak dapat melihat mengapa harus ada kunci sama sekali.
Drew Noakes
7
Hapus itu, lalu jalankan kembali rangkaian pengujian cakupan kode 100% Anda. Apa itu? Konsultan sebelumnya tidak membuatnya?
Spacedman

Jawaban:

82

Saya tidak akan terkejut jika seseorang yang melihat ini:

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

dan mengira dia bisa memotong jumlah baris.

Saya akan sangat khawatir jika itu masalahnya ...

cjk
sumber
4
Dia mungkin melihat metode yang disebut "newObject ()" dan metode ini mengembalikan instance tunggal, tetapi dia berkata "hei, bukankah c # memiliki kata kunci untuk itu"?
Amiram Korach
9
Memang terdengar seperti pekerjaan refactoring tanpa memahami secara efektif apa yang sedang terjadi.
Aphelion
1
@OrangeDog: Sayangnya, itu tidak mungkin, karena kode terkait telah ditulis sebelum saya bergabung dengan perusahaan. Sekarang karena ada perubahan yang harus dilakukan, mungkin saya bisa meyakinkan Manajemen untuk mengizinkan saya memperbaiki kodenya. Jika tidak, saya tidak akan bertanggung jawab atas ketidakstabilan apa pun (yang terakhir menyentuh apa pun adalah yang harus disalahkan) ...
2
@Ibruder Prioritas yang lebih tinggi adalah meyakinkan Manajemen bahwa mereka memerlukan kontrol versi, pengujian otomatis, dan sistem tinjauan. Jika orang terakhir yang menyentuh sesuatu adalah orang yang harus disalahkan, maka kedengarannya bukan perusahaan yang bagus untuk bekerja.
OrangeDog
1
Saya tidak terlalu peduli dengan penguncian yang jelas rusak - semua orang telah menunjukkannya, tetapi +1 hanya untuk 'atau program di iOS sebelum 4/5' <g>
Martin James
15

Inilah pertanyaan serupa, dan jawabannya:

Kunci memastikan pengecualian timbal balik - tidak lebih dari satu utas yang dapat menahan kunci pada saat yang bersamaan. Kunci diidentifikasi dengan contoh objek tertentu. Anda membuat objek baru untuk dikunci setiap saat dan Anda tidak memiliki cara apa pun untuk memberi tahu utas lain untuk mengunci objek yang sama persis. Oleh karena itu, penguncian Anda tidak berguna.

JleruOHeP
sumber
2

Mungkin tidak berguna. Tapi ada kemungkinan itu ada untuk menciptakan penghalang memori. Tidak yakin apakah c # tidak mengunci elisi atau apakah itu mempertahankan semantik urutan kunci.

benmmurphy
sumber
Itu terjadi beberapa tahun yang lalu tetapi Anda benar-benar berhak mendapatkan +1 karena menyatakan fakta yang jelas ini yang diabaikan oleh sebagian orang. Misalnya, pada Universal Windows Platform tidak ada metode MemoryBarrier () dan sihir dengan Interlocked. BandingkanExchange dan kunci (Objek baru ()) menjadi satu-satunya cara untuk menangani beberapa masalah.
Sergey.quixoticaxis.Ivanov
Aku bahkan tidak tahu C # mengizinkan ini. Senang sekali Anda menunjukkannya.
Semua orang