คำถามนี้เกี่ยวกับภาษา C # แต่ฉันคาดหวังให้ครอบคลุมภาษาอื่นเช่น Java หรือ TypeScript
Microsoft แนะนำแนวทางปฏิบัติที่ดีที่สุดในการใช้การโทรแบบอะซิงโครนัสใน. NET ในบรรดาคำแนะนำเหล่านี้เรามาเลือกสองข้อ:
- เปลี่ยนลายเซ็นของเมธอด async เพื่อให้ส่งคืนงานหรืองาน <> (ใน TypeScript นั่นจะเป็นสัญญา <>)
- เปลี่ยนชื่อของวิธีการ async เป็นลงท้ายด้วย xxxAsync ()
ตอนนี้เมื่อแทนที่ส่วนประกอบที่มีระดับต่ำและซิงโครนัสด้วยอะซิงก์หนึ่งสิ่งนี้จะส่งผลกระทบต่อสแต็กเต็มของแอปพลิเคชัน เนื่องจาก async / await มีผลกระทบเชิงบวกต่อเมื่อใช้ "all-up up" เท่านั้นนั่นหมายถึงชื่อลายเซ็นและเมธอดของทุกเลเยอร์ในแอปพลิเคชันจะต้องเปลี่ยน
สถาปัตยกรรมที่ดีมักจะเกี่ยวข้องกับการวาง abstractions ระหว่างแต่ละเลเยอร์เช่นการแทนที่ส่วนประกอบระดับต่ำโดยผู้อื่นจะมองไม่เห็นโดยส่วนประกอบระดับบน ใน C # abstractions จะอยู่ในรูปของอินเตอร์เฟส หากเราแนะนำส่วนประกอบ async ใหม่ระดับต่ำและต่ำแต่ละอินเตอร์เฟสใน call stack จำเป็นต้องได้รับการแก้ไขหรือแทนที่ด้วยอินเตอร์เฟสใหม่ วิธีการแก้ไขปัญหา (async หรือ sync) ในชั้นเรียนการใช้งานจะไม่ถูกซ่อน (abstracted) กับผู้โทรอีกต่อไป ผู้โทรต้องทราบว่าซิงค์หรือไม่
async / รอปฏิบัติที่ดีที่สุดไม่ตรงข้ามกับหลักการ "สถาปัตยกรรมที่ดี" หรือไม่?
หมายความว่าแต่ละอินเทอร์เฟซ (พูดว่า IEnumerable, IDataAccessLayer) จำเป็นต้องมีการซิงค์แบบอะซิงโครนัส (IAsyncEnumerable, IAsyncDataAccessLayer) เพื่อให้สามารถแทนที่ในสแต็กเมื่อสลับเป็นการพึ่งพาแบบอะซิงโครนัส
หากเราผลักดันปัญหาไปอีกสักหน่อยคงไม่เป็นการง่ายกว่าที่จะสมมติว่าทุกวิธีเป็นแบบซิงค์ (เพื่อส่งคืนภารกิจ <> หรือสัญญา <>) และสำหรับวิธีการซิงโครไนซ์การโทรแบบอะซิงโครไนซ์เมื่อไม่จริง async? นี่เป็นสิ่งที่คาดหวังจากภาษาการเขียนโปรแกรมในอนาคตหรือไม่
CancellationToken
และผู้ที่อาจต้องการให้เป็นค่าเริ่มต้น) การลบวิธีการซิงค์ที่มีอยู่ (และทำลายรหัสทั้งหมดในเชิงรุก) เป็นสิ่งที่ไม่ใช่การเริ่มต้นที่ชัดเจน