ไลบรารีงาน async ของฉันควรกลืนข้อยกเว้นอย่างเงียบ ๆ หรือไม่?


10

ฉันได้เรียนรู้เพียงแค่ว่า .NET 4.5 แนะนำการเปลี่ยนแปลงวิธีการข้อยกเว้นภายในTaskได้รับการจัดการ กล่าวคือพวกเขาถูกระงับอย่างเงียบ ๆ

การให้เหตุผลอย่างเป็นทางการว่าทำไมสิ่งนี้เสร็จสิ้นดูเหมือนจะเป็น "เราต้องการที่จะเป็นมิตรกับนักพัฒนามือใหม่":

ใน. NET 4.5 งานมีความโดดเด่นมากกว่าที่เคยทำใน. NET 4 อย่างมากเนื่องจากมีการใช้ภาษา C # และ Visual Basic เป็นส่วนหนึ่งของคุณลักษณะ async ใหม่ที่สนับสนุนโดยภาษา สิ่งนี้ทำให้ย้ายงานออกจากโดเมนของนักพัฒนาที่มีประสบการณ์มาสู่อาณาจักรของทุกคน เป็นผลให้มันนำไปสู่การแลกเปลี่ยนชุดใหม่เกี่ยวกับความเข้มงวดในการจัดการข้อยกเว้น

(ที่มา )

ฉันได้เรียนรู้ที่จะเชื่อมั่นว่าการตัดสินใจใน. NET หลายครั้งนั้นเกิดขึ้นจากคนที่รู้ว่าพวกเขากำลังทำอะไรอยู่และมักจะมีเหตุผลที่ดีที่อยู่เบื้องหลังสิ่งที่พวกเขาตัดสินใจ แต่อันนี้หนีฉัน

ถ้าฉันออกแบบไลบรารีงาน async ของฉันเองข้อดีของการกลืนข้อยกเว้นที่นักพัฒนาของ Framework เห็นว่าฉันไม่เห็นคืออะไร


4
+1 คำถามที่ดีเนื่องจากความจริงที่ว่าการไม่เผยแพร่ข้อยกเว้นที่คุณไม่สามารถจัดการได้นั้นถือเป็นการปฏิบัติที่ไม่ดีแม้จะอยู่ในบริบทที่ไม่ตรงกันก็ตาม นอกจากนี้ข้อโต้แย้งเกี่ยวกับนักพัฒนาที่ไม่มีประสบการณ์ก็ค่อนข้างง่อย IMHO อะไรจะน่าแปลกใจสำหรับผู้เริ่มต้นมากกว่าชิ้นส่วนของรหัสที่ไม่เพียง แต่ใช้งานไม่ได้ แต่ยังไม่มีข้อยกเว้นใด ๆ เลย?
— Arseni Mourzenko

@MainMa ความคิดของฉัน แต่ฉันเคยผิดมาก่อน (เมื่อปรากฏว่าพวกเขาทำในความเป็นจริงมีเหตุผลที่ดีมาก แต่ไม่ชัดเจน) ดังนั้นฉันคิดว่าฉันถาม
— Roman Starkov

2
ว้าวฉันดีใจที่คุณโพสต์ข้อความนี้เพราะมันเป็นครั้งแรกที่ฉันได้ยิน และมันแน่นอนละเมิดPOLA คุณพูดถูกว่าพวกเขารู้จริง ๆ ว่าพวกเขากำลังทำอะไรดังนั้นฉันก็อยากรู้อยากเห็นอย่างจริงใจว่าการใช้เหตุผลอะไรที่อยู่เบื้องหลังสิ่งนี้ ... ขณะที่ก้นถูกส่งผ่านไปยัง coroutine ..
— จิมมี่ฮอฟฟา

คำตอบ:


2

สำหรับสิ่งที่คุ้มค่าเอกสารที่คุณเชื่อมโยงเพื่อให้กรณีตัวอย่างเป็นเหตุผล:

Task op1 = FooAsync(); 
Task op2 = BarAsync(); 
await op1; 
await op2;

ในรหัสนี้ผู้พัฒนากำลังเรียกใช้การดำเนินการแบบอะซิงโครนัสสองครั้งเพื่อให้ทำงานแบบขนานและจากนั้นรอแบบอะซิงโครนัสโดยใช้คุณสมบัติภาษาใหม่ที่รอคอย ... [C] onsider จะเกิดอะไรขึ้น รอ op1 จะเผยแพร่ข้อยกเว้นของ op1 และดังนั้น op2 จะไม่ถูกรอคอย เป็นผลให้ข้อยกเว้นของ op2 จะไม่ถูกสังเกตและกระบวนการจะล้มเหลวในที่สุด

เพื่อให้ง่ายขึ้นสำหรับนักพัฒนาในการเขียนรหัสแบบอะซิงโครนัสที่ยึดตามงาน. NET 4.5 เปลี่ยนลักษณะการทำงานข้อยกเว้นเริ่มต้นสำหรับข้อยกเว้นที่ไม่ได้สังเกต ในขณะที่ข้อยกเว้นที่ไม่ได้สังเกตเห็นจะยังคงทำให้เกิดเหตุการณ์ UnobservedTaskException ที่จะเพิ่มขึ้น (ไม่ทำเช่นนั้นจะเป็นการเปลี่ยนแปลงทำลาย) กระบวนการจะไม่ผิดพลาดโดยค่าเริ่มต้น แต่ข้อยกเว้นจะจบลงด้วยการกินหลังจากเหตุการณ์ถูกยกขึ้นโดยไม่คำนึงว่าตัวจัดการเหตุการณ์สังเกตข้อยกเว้นหรือไม่

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

พฤติกรรมนั้นสามารถกำหนดค่าได้ - แต่แน่นอนว่า 99% ของนักพัฒนากำลังจะใช้พฤติกรรมเริ่มต้นโดยไม่คิดถึงปัญหานี้ ดังนั้นสิ่งที่พวกเขาเลือกเป็นค่าเริ่มต้นเป็นเรื่องใหญ่


แต่คุณจะได้รับข้อยกเว้นปกติop1ใช่ไหม ถ้าสิ่งนั้นยังไม่ถูกจัดการมันจะทำให้กระบวนการใช่ไหม?
— Timwi

1
@Timwi ตามที่ฉันเข้าใจไม่มีop1ข้อยกเว้นและop2ข้อยกเว้นของจะทำให้โปรแกรมลง ข้อดีคือคุณมีโอกาสสังเกตทั้งคู่ แต่ถ้าคุณไม่ทำทั้งคู่จะถูกกลืน ฉันอาจจะผิด แต่

ฉันประหลาดใจจริงๆที่พวกเขาพบว่ามันสำคัญมากที่จะให้คุณ "สังเกต" ทั้งคู่ หากคุณต้องการที่จะ "สังเกต" พวกเขาคุณจะจับพวกเขาและรายงานสิ่งที่เกิดขึ้นผ่านผลงาน! ... เห็นด้วยกับเหตุผลของคุณ +1
— Roman Starkov

2

TL; DR - ไม่คุณไม่ควรมองข้ามข้อยกเว้นอย่างเงียบ ๆ


ลองดูที่สมมติฐาน

  • ศรัทธาที่ตาบอดของคุณ

ฉันได้เรียนรู้ที่จะเชื่อมั่นว่าการตัดสินใจใน. NET หลายครั้งนั้นเกิดขึ้นจากคนที่รู้ว่าพวกเขากำลังทำอะไรอยู่และมักจะมีเหตุผลที่ดีที่อยู่เบื้องหลังสิ่งที่พวกเขาตัดสินใจ แต่อันนี้หนีฉัน

MS มีพนักงานที่ยอดเยี่ยมจริงๆบางคนไม่ต้องสงสัยเลย พวกเขายังมีผู้จัดการและผู้บริหารจำนวนมากที่ ... ไร้เดียงสาและตัดสินใจอย่างไม่ดีอยู่เสมอ เท่าที่เราอยากจะเชื่อเทพนิยายของนักวิทยาศาสตร์ที่มีความชำนาญทางเทคนิคที่ขับเคลื่อนการพัฒนาผลิตภัณฑ์ความเป็นจริงนั้นน่ากลัวยิ่งกว่า

ประเด็นของฉันคือถ้าสัญชาตญาณของคุณบอกคุณว่ามีอะไรผิดปกติก็มีโอกาสที่ดี (และแบบอย่างที่ผ่านมา) ว่ามันผิด

  • นี่เป็นปัญหาทางเทคนิค

วิธีจัดการกับข้อยกเว้นในกรณีนี้คือการตัดสินใจปัจจัยมนุษย์ไม่ใช่การตัดสินใจทางเทคนิค ข้อยกเว้นคือข้อผิดพลาด การนำเสนอข้อผิดพลาดแม้ว่าการจัดรูปแบบไม่ดีให้ข้อมูลที่สำคัญกับผู้ใช้ กล่าวคือมีบางอย่างผิดพลาด

พิจารณาบทสนทนาสมมุตินี้ระหว่างผู้ใช้ปลายทางและผู้พัฒนา

ผู้ใช้: แอปชำรุด
Dev: มีอะไรแตก?
ผู้ใช้: ฉันไม่รู้ฉันคลิกที่ปุ่มและไม่มีอะไรเกิดขึ้น
Dev: คุณหมายถึงอะไรโดยไม่มีอะไรเกิดขึ้น?
ผู้ใช้: ดูฉันคลิกฉันรอและรอและฉันรอและไม่มีอะไร ... มันแตกหักอย่างเห็นได้ชัด

ตอนนี้ผู้พัฒนาที่โชคไม่ดีสมมุติฐานของเราในตอนนี้ต้องเข้าใจว่าเกิดอะไรขึ้นในสายของเหตุการณ์ มันอยู่ที่ไหน?
การแจ้งเตือนตัวจัดการเหตุการณ์ -> กิจวัตรเพื่อจัดการเหตุการณ์ -> วิธีที่ทริกเกอร์โดยตัวจัดการ -> จุดเริ่มต้นของการโทรแบบอะซิงโครนัส -> เครือข่าย OSI 7 ชั้น -> การส่งสัญญาณทางกายภาพ -> สำรองเครือข่าย OSI 7 ชั้น -> บริการรับ -> วิธีการที่เรียกโดยบริการ -> ... -> ตอบกลับส่งโดยบริการ -> .... -> ใบเสร็จรับเงิน asynch -> การประมวลผลการตอบกลับ asynch -> ...

และโปรดทราบว่าฉันได้คัดลอกเส้นทางที่ผิดพลาดหลายเส้นทางที่นั่น


หลังจากพูดถึงข้อสันนิษฐานบางอย่างแล้วฉันคิดว่ามันชัดเจนมากขึ้นว่าทำไมการระงับข้อยกเว้นอย่างเงียบ ๆ เป็นความคิดที่ไม่ดี ข้อยกเว้นและข้อความแสดงข้อผิดพลาดที่เกี่ยวข้องเป็นตัวบ่งชี้สำคัญสำหรับผู้ใช้ว่ามีบางอย่างผิดปกติ แม้ว่าข้อความนั้นจะไม่มีความหมายต่อผู้ใช้ปลายทาง แต่ข้อมูลที่ฝังตัวอาจเป็นประโยชน์ต่อนักพัฒนาในการทำความเข้าใจกับสิ่งที่ผิดพลาด หากพวกเขาโชคดีข้อความจะนำไปสู่การแก้ปัญหาด้วยซ้ำ

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

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

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

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