ฉันมีแอปพลิเคชันที่ฉันมีทรัพยากรที่ใช้ร่วมกัน (ระบบ Motion) ซึ่งลูกค้าหลายรายสามารถเข้าถึงได้ ฉันมีการดำเนินการส่วนบุคคลที่ต้องการการเข้าถึงระบบในช่วงระยะเวลาของการย้าย และการดำเนินการใดควรทำให้เกิดข้อยกเว้น 'ไม่ว่าง' หากมีการร้องขอการดำเนินการที่ขัดแย้งกันในเวลาเดียวกัน ฉันยังมีซีเควนเซอร์ซึ่งจำเป็นต้องได้รับสิทธิ์การเข้าถึงระบบ Motion แบบเอกสิทธิ์เฉพาะบุคคลเพื่อดำเนินการต่างๆ สลับกับการกระทำอื่นๆ ในระหว่างลำดับทั้งหมด ไคลเอ็นต์อื่นไม่ควรสามารถรัน Operations ได้
ฉันได้เข้าหาสิ่งนี้แบบดั้งเดิมโดยใช้ความสัมพันธ์ของเธรด เพื่อให้เธรดสามารถร้องขอการเข้าถึงแบบเอกสิทธิ์เฉพาะบุคคลและเรียกใช้การบล็อกการโทรที่สอดคล้องกับการดำเนินการ ในขณะที่เธรดมีสิทธิ์เข้าถึง ไม่มีเธรดอื่นใดที่สามารถใช้ทรัพยากรได้ ปัญหาที่ฉันมีตอนนี้คือฉันได้ก้าวไปสู่การนำระบบของฉันไปใช้โดยใช้รูปแบบ async/await เพื่อให้มีการใช้ซีเควนเซอร์ที่สะอาดกว่า ปัญหาคือตอนนี้ซีเควนเซอร์ของฉันไม่ได้ทำงานบนเธรดเดียวกันเสมอไป เธรดที่ใช้งานอยู่สามารถเปลี่ยนแปลงได้ในระหว่างการโทรกลับ ดังนั้นจึงไม่ใช่เรื่องง่ายอีกต่อไปที่จะตัดสินว่าฉันอยู่ในบริบทที่ถูกต้องเพื่อดำเนินการต่อไปหรือไม่ สิ่งหนึ่งที่ควรทราบก็คือ การดำเนินการบางอย่างนั้นประกอบด้วยการรอคอย ซึ่งหมายความว่าทั้งลำดับและการดำเนินการแต่ละรายการสามารถขยายได้หลายเธรด
คำถามของฉัน: มีใครทราบรูปแบบที่ดีในการจัดการกับการรับสิทธิ์การเข้าถึงแบบเอกสิทธิ์เฉพาะบุคคลเมื่อมีการสลับเธรดเนื่องจาก async/await หรือไม่
เพื่อการอ้างอิง บางสิ่งที่ฉันได้พิจารณา:
ฉันสามารถสร้าง SynchronizationContext แบบกำหนดเองที่รวบรวมการเรียกซีเควนเซอร์ทั้งหมดในช่วงเวลาของลำดับกลับไปยังเธรดเดียว สิ่งนี้มีประโยชน์ในการอนุญาตให้ฉันนำรหัสการจัดการการเข้าถึงความสัมพันธ์ของเธรดที่มีอยู่กลับมาใช้ใหม่ได้ ข้อเสียคือจะต้องทุ่มเทเธรดทุกครั้งที่ฉันทำลำดับหรือการดำเนินการ (เนื่องจากการดำเนินการสามารถขยายหลายเธรดได้)
สร้างโทเค็นการเข้าถึงที่สามารถรับได้เพื่อส่งผ่านไปยังวิธีดำเนินการเพื่อพิสูจน์ว่าคุณได้รับสิทธิ์การเข้าถึง นี่เป็นข้อเสียของการบวมวิธีการด้วยพารามิเตอร์โทเค็น
ใช้วิธีการโทเค็นการเข้าถึงจาก (2) แต่สร้างการใช้งานอินเทอร์เฟซที่ซ้ำกันสำหรับอินเทอร์เฟซการดำเนินงานเพื่อให้สามารถสร้าง wrapper ได้ทันทีด้วยโทเค็น 'baked-in' สิ่งนี้จะสร้างโค้ดกาวที่น่าเกลียด แต่จะล้างโค้ดซีเควนเซอร์เพื่อไม่ให้ต้องส่งโทเค็นไปยังแต่ละวิธีอีกต่อไป