lock (วัตถุใหม่ ()) - ลัทธิขนส่งสินค้าหรือ "กรณีพิเศษทางภาษา" ที่บ้าคลั่ง?


88

ฉันกำลังตรวจสอบโค้ดบางส่วนที่เขียนโดยที่ปรึกษาและในขณะที่มีธงสีแดงหลายสิบอันโผล่ขึ้นมาแล้วฉันไม่สามารถคาดเดาข้อมูลโค้ดต่อไปนี้ได้:

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

lock (วัตถุใหม่ ()) กำลังทำอะไรที่นี่ ไม่ควรมีผลกระทบใด ๆ เนื่องจากมักจะล็อกวัตถุอื่นอยู่เสมอ แต่การล็อกแบบนี้จะคงอยู่ตลอดทั้งรหัสแม้ในส่วนที่ไม่ได้คัดลอกและวาง นี่เป็นกรณีพิเศษบางอย่างในภาษา C # ที่รวบรวมสิ่งที่ฉันไม่รู้หรือโปรแกรมเมอร์เพิ่งนำลัทธิขนส่งสินค้าบางอย่างที่เกิดขึ้นเมื่อไม่นานมานี้มาใช้?


19
ฉันคิดว่าพวกเขาสับสนมาก พวกเขาอาจเห็นว่ามันnew object()ถูกเก็บไว้ที่ใดในฟิลด์และฟิลด์นั้นถูกใช้ในlock()คำสั่งและพวกเขาไม่รู้ดีกว่าที่จะไม่อินไลน์มัน
Damien_The_Unbeliever

21
"ที่ปรึกษา" คนนั้นอธิบายให้ทำ ... คุณไม่ผิด: lockรหัสนั้นไม่มีประโยชน์เลย
Marc Gravell

12
@Baboon: ถ้าคุณไม่ใช่คนที่ต้องทำการ refactoring ...

2
นอกจากนี้ถ้านี่เป็น WinForms ฉันก็ไม่เห็นว่าทำไมจึงควรมีการล็อคที่นั่นเลย
Drew Noakes

7
ลบออกแล้วเรียกใช้ชุดทดสอบความครอบคลุมรหัส 100% อีกครั้ง นั่นอะไร? ที่ปรึกษาก่อนหน้านี้ไม่ได้สร้างขึ้นมา?
Spacedman

คำตอบ:


83

ฉันจะไม่แปลกใจถ้าเป็นคนที่เห็นสิ่งนี้:

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

และคิดว่าเขาสามารถตัดจำนวนบรรทัดได้

ฉันจะกังวลมากถ้าเป็นอย่างนั้น ...


4
เขาอาจเห็นเมธอดที่เรียกว่า "newObject ()" และวิธีนี้ส่งคืนอินสแตนซ์ซิงเกิลตัน แต่เขาบอกว่า "เฮ้ c # ไม่มีคีย์เวิร์ดสำหรับสิ่งนั้น"?
Amiram Korach

9
ดูเหมือนจะเป็นงาน refactoring โดยที่ไม่เข้าใจว่าเกิดอะไรขึ้น
Myrtle

1
@OrangeDog: น่าเศร้าที่เป็นไปไม่ได้เนื่องจากรหัสที่เกี่ยวข้องถูกเขียนขึ้นก่อนที่ฉันจะเข้าร่วม บริษัท ตอนนี้มีการเปลี่ยนแปลงที่ต้องทำบางทีฉันอาจโน้มน้าวให้ฝ่ายบริหารให้ฉันแก้ไขโค้ดได้ มิฉะนั้นฉันจะไม่รับผิดชอบต่อความไม่แน่นอนใด ๆ (คนสุดท้ายที่แตะต้องสิ่งใดคือสิ่งที่ต้องตำหนิ) ...

2
@Ibruder ลำดับความสำคัญที่สูงกว่าคือการโน้มน้าวผู้บริหารว่าพวกเขาต้องการการควบคุมเวอร์ชันการทดสอบอัตโนมัติและระบบตรวจสอบ หากคนสุดท้ายที่จะแตะต้องสิ่งใดเป็นสิ่งที่ต้องตำหนิมันก็ไม่ได้ฟังดูเป็น บริษัท ที่ดีมากที่จะทำงานให้
OrangeDog

1
ฉันไม่สนใจมากนักเกี่ยวกับการล็อคที่เสียอย่างเห็นได้ชัด - คนอื่น ๆ ได้ชี้ให้เห็นแล้ว แต่ +1 สำหรับ 'หรือโปรแกรมบน iOS ก่อน 4/5' <g>
Martin James

15

นี่คือคำถามที่คล้ายกันและคำตอบ:

การล็อคช่วยให้แน่ใจว่ามีการยกเว้นซึ่งกันและกัน - ไม่สามารถล็อคได้มากกว่าหนึ่งเธรดในเวลาเดียวกัน ล็อคถูกระบุด้วยอินสแตนซ์ออบเจ็กต์เฉพาะ คุณกำลังสร้างอ็อบเจ็กต์ใหม่เพื่อล็อกทุกครั้งและคุณไม่มีทางแจ้งเธรดอื่นใดให้ล็อกอินสแตนซ์อ็อบเจ็กต์เดียวกันนั้นแน่นอน ดังนั้นการล็อคของคุณจะไม่มีประโยชน์


2

มันคงไม่มีประโยชน์ แต่มีโอกาสที่จะสร้างกำแพงความทรงจำ ไม่แน่ใจว่า c # ล็อค elision หรือไม่หรือว่ามันรักษาความหมายของการสั่งซื้อของล็อคหรือไม่


ไม่กี่ปีที่ผ่านมา แต่ผู้ชายคุณสมควรได้รับ +1 โดยสิ้นเชิงสำหรับการระบุความจริงที่ชัดเจนนี้ซึ่งบางคนเพิกเฉยโดยสิ้นเชิง ตัวอย่างเช่นบนแพลตฟอร์ม Universal Windows ไม่มีเมธอด MemoryBarrier () และเวทมนตร์ที่มี Interlocked เปรียบเทียบแลกเปลี่ยนและล็อค (วัตถุใหม่ ()) กลายเป็นวิธีเดียวในการจัดการกับปัญหาบางอย่าง
Sergey.quixoticaxis Ivanov

ฉันไม่รู้ด้วยซ้ำว่า C # อนุญาตสิ่งนี้ เยี่ยมมากที่จะชี้ให้เห็น
ทุกคน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.