ฉันถือว่านี่เป็นการใช้ข้อความในทางที่ผิด ฉันรู้ว่าฉันเป็นคนส่วนน้อยในตำแหน่งนี้
ฉันถือว่านี่เป็นการละเมิดด้วยเหตุผลสามประการ
ประการแรกเนื่องจากฉันคาดหวังว่า "การใช้" จะถูกใช้เพื่อใช้ทรัพยากรและกำจัดทิ้งเมื่อคุณใช้งานเสร็จแล้ว การเปลี่ยนสถานะโปรแกรมไม่ได้ใช้ทรัพยากรและการเปลี่ยนกลับไม่ได้เป็นการกำจัดสิ่งใด ๆ ดังนั้นการ "ใช้" เพื่อกลายพันธุ์และฟื้นฟูสภาพจึงเป็นการละเมิด รหัสทำให้ผู้อ่านเข้าใจผิด
ประการที่สองเพราะผมคาดหวังว่า "ใช้" ที่จะใช้ออกจากความสุภาพไม่จำเป็น เหตุผลที่คุณใช้ "ใช้" เพื่อกำจัดไฟล์เมื่อคุณทำเสร็จแล้วไม่ใช่เพราะจำเป็นต้องทำเช่นนั้น แต่เป็นเพราะมันสุภาพ - อาจมีคนอื่นรอที่จะใช้ไฟล์นั้นดังนั้นการพูดว่า "เสร็จสิ้น ตอนนี้ "เป็นสิ่งที่ถูกต้องตามหลักศีลธรรมที่ควรทำ ฉันคาดหวังว่าฉันควรจะสามารถปรับเปลี่ยน "การใช้งาน" เพื่อให้ทรัพยากรที่ใช้นั้นถูกกักเก็บไว้นานขึ้นและถูกกำจัดทิ้งในภายหลังและผลกระทบเพียงอย่างเดียวของการทำเช่นนั้นก็คือความไม่สะดวกเล็กน้อยกระบวนการอื่น ๆ ที่เล็กน้อยในความไม่สะดวกกระบวนการอื่นบล็อก "ใช้" ซึ่งมีผลกระทบทางความหมายต่อสถานะของโปรแกรมไม่เหมาะสมเพราะมันซ่อนความสำคัญไว้ จำเป็นต้องมีการกลายพันธุ์ของสถานะโปรแกรมในโครงสร้างที่ดูเหมือนว่ามีเพื่อความสะดวกและสุภาพไม่ใช่ความจำเป็น
และประการที่สามการกระทำของโปรแกรมของคุณถูกกำหนดโดยสถานะของโปรแกรม ความจำเป็นในการปรับเปลี่ยนสถานะอย่างรอบคอบเป็นเหตุให้เรามีการสนทนากันตั้งแต่แรก ลองพิจารณาว่าเราจะวิเคราะห์โปรแกรมเดิมของคุณได้อย่างไร
คุณจะนำสิ่งนี้ไปตรวจสอบโค้ดในสำนักงานของฉันหรือไม่คำถามแรกที่ฉันจะถามคือ "มันถูกต้องจริงๆหรือไม่ที่จะล็อคกบหากมีข้อยกเว้นเกิดขึ้น" เห็นได้ชัดอย่างชัดเจนจากโปรแกรมของคุณว่าสิ่งนี้จะล็อกสิ่งนี้อีกครั้งอย่างจริงจังไม่ว่าจะเกิดอะไรขึ้น นั่นถูกต้องใช่ไหม? เกิดข้อยกเว้น โปรแกรมอยู่ในสถานะที่ไม่รู้จัก เราไม่รู้ว่า Foo, Fiddle หรือ Bar โยนทำไมพวกเขาถึงโยนหรือการกลายพันธุ์ที่พวกเขาทำไปยังสถานะอื่นที่ไม่ได้รับการทำความสะอาด คุณสามารถทำให้ฉันมั่นใจได้ไหมว่าในสถานการณ์ที่เลวร้ายนั้นเป็นสิ่งที่ถูกต้องเสมอที่จะล็อคใหม่
บางทีมันอาจจะไม่ใช่ จุดของฉันคือว่ามีรหัสที่มันถูกเขียนเดิม, รหัสวิจารณ์รู้ที่จะถามคำถาม ด้วยรหัสที่ใช้ "ใช้" ฉันไม่รู้จะถามคำถาม; ฉันคิดว่าบล็อก "ใช้" จะจัดสรรทรัพยากรใช้มันเพียงเล็กน้อยและทิ้งอย่างสุภาพเมื่อดำเนินการเสร็จแล้วไม่ใช่ว่าการปิดกั้นของบล็อก "ใช้" จะทำให้สถานะโปรแกรมของฉันกลายเป็นสถานการณ์ที่ไม่ปกติเมื่อหลายคนตามอำเภอใจ เงื่อนไขความสอดคล้องของสถานะโปรแกรมถูกละเมิด
การใช้บล็อก "ใช้" เพื่อให้มีผลทางความหมายทำให้ส่วนของโปรแกรมนี้:
}
มีความหมายอย่างยิ่ง เมื่อฉันมองไปที่วงเล็บปีกกาเดี่ยวนั้นฉันไม่คิดในทันทีว่า "การรั้งนั้นมีผลข้างเคียงซึ่งส่งผลกระทบอย่างกว้างขวางต่อสถานะทั่วโลกของโปรแกรมของฉัน" แต่เมื่อคุณละเมิด "โดยใช้" แบบนี้จู่ๆมันก็ทำ
สิ่งที่สองที่ฉันจะถามหากฉันเห็นรหัสเดิมของคุณคือ "จะเกิดอะไรขึ้นหากมีข้อยกเว้นเกิดขึ้นหลังจากการปลดล็อก แต่ก่อนที่จะทำการลองใหม่" หากคุณกำลังเรียกใช้แอสเซมบลีที่ไม่ได้ปรับให้เหมาะสมคอมไพลเลอร์อาจแทรกคำสั่ง no-op ก่อนการลองและเป็นไปได้ที่ข้อยกเว้นการยกเลิกเธรดจะเกิดขึ้นบน no-op สิ่งนี้หายาก แต่มันเกิดขึ้นในชีวิตจริงโดยเฉพาะบนเว็บเซิร์ฟเวอร์ ในกรณีนี้การปลดล็อกจะเกิดขึ้น แต่การล็อกไม่เกิดขึ้นเนื่องจากข้อยกเว้นเกิดขึ้นก่อนการลอง เป็นไปได้ทั้งหมดว่าโค้ดนี้มีความเสี่ยงต่อปัญหานี้และควรเขียนขึ้นมา
bool needsLock = false;
try
{
// must be carefully written so that needsLock is set
// if and only if the unlock happened:
this.Frobble.AtomicUnlock(ref needsLock);
blah blah blah
}
finally
{
if (needsLock) this.Frobble.Lock();
}
อีกครั้งบางทีมันอาจจะไม่บางทีมันอาจจะไม่ได้ แต่ฉันรู้ว่าจะถามคำถาม ด้วยเวอร์ชัน "ใช้" จะมีความอ่อนไหวต่อปัญหาเดียวกัน: ข้อยกเว้นการยกเลิกเธรดอาจเกิดขึ้นได้หลังจากที่ Frobble ถูกล็อก แต่ก่อนที่จะป้อนขอบเขตการป้องกันที่เกี่ยวข้องกับการใช้งาน แต่ด้วยเวอร์ชัน "ใช้" ฉันถือว่านี่คือ "แล้วไง" สถานการณ์. เป็นเรื่องที่น่าเสียดายหากเกิดเหตุการณ์เช่นนี้ขึ้น แต่ฉันคิดว่าการ "ใช้" นั้นเป็นไปเพื่อความสุภาพเท่านั้นไม่ทำให้สถานะโปรแกรมที่สำคัญอย่างยิ่งกลายพันธุ์ ฉันคิดว่าหากข้อยกเว้นการยกเลิกเธรดที่น่ากลัวบางอย่างเกิดขึ้นในเวลาที่ไม่ถูกต้องนักสะสมขยะจะล้างทรัพยากรนั้นในที่สุดโดยการเรียกใช้โปรแกรมสุดท้าย