เมื่อเร็ว ๆ นี้ดูเหมือนว่าฉันจะไม่สามารถรับรูปแบบasync-await ที่น่าทึ่งของ C # 5.0 ได้ คุณอยู่ที่ไหนตลอดชีวิตของฉัน
ฉันตื่นเต้นอย่างมากกับไวยากรณ์ที่เรียบง่าย แต่ฉันมีปัญหาเล็กน้อย ปัญหาของฉันคือฟังก์ชั่น async มีการประกาศที่แตกต่างกันโดยสิ้นเชิงจากฟังก์ชั่นปกติ เนื่องจากมีเพียง async เท่านั้นที่สามารถรอฟังก์ชั่นอื่น ๆ ของ async ได้เมื่อฉันพยายามที่จะแปลงรหัสการบล็อกเก่า ๆ ให้เป็น async ฉันจึงมีผลกระทบโดมิโนของฟังก์ชั่นที่ฉันต้องแปลง
คนได้รับการอ้างถึงนี้เป็นทำลายผีดิบ เมื่อ async เริ่มกัดรหัสของคุณมันก็จะยิ่งใหญ่ขึ้นเรื่อย ๆ กระบวนการ porting ไม่ยากมันเป็นเพียงแค่การขว้างปาในการประกาศและการตัดค่าตอบแทนด้วยasync
Task<>
แต่มันเป็นเรื่องที่น่ารำคาญที่จะทำเช่นนี้ซ้ำแล้วซ้ำอีกเมื่อทำการพอร์ตรหัสซิงโครนัสเก่า
ดูเหมือนว่าฉันจะเป็นธรรมชาติมากขึ้นถ้าทั้งสองประเภทฟังก์ชั่น (async และซิงค์เก่าธรรมดา) มีไวยากรณ์เดียวกันแน่นอน หากเป็นกรณีนี้การย้ายจะใช้ความพยายามเป็นศูนย์และฉันสามารถสลับระหว่างสองรูปแบบได้อย่างไม่ลำบาก
ฉันคิดว่าสิ่งนี้สามารถใช้งานได้หากเราปฏิบัติตามกฎเหล่านี้:
ฟังก์ชัน Async ไม่จำเป็นต้องมีการ
async
ประกาศอีกต่อไปTask<>
ประเภทการกลับมาของพวกเขาจะได้ไม่ต้องถูกห่อใน คอมไพเลอร์จะระบุฟังก์ชั่น async ระหว่างการคอมไพล์ด้วยตัวเองและทำการตัดคำสั่งงาน <> โดยอัตโนมัติตามต้องการไม่มีการเรียกและฟังก์ชั่น async ที่ใช้ไฟและลืมได้อีก หากคุณต้องการเรียกใช้ฟังก์ชัน async คุณจะต้องรอ ฉันแทบจะไม่ใช้ไฟและลืมไปเลยและตัวอย่างทั้งหมดของเงื่อนไขการแข่งขันที่บ้าคลั่งหรือการหยุดชะงักมักจะเป็นไปตามพวกเขา ฉันคิดว่าพวกเขาสับสนเกินไปและ "ไม่ทันรู้ตัว" ด้วยความคิดแบบซิงโครนัสที่เราพยายามยกระดับ
หากคุณไม่สามารถอยู่ได้โดยปราศจากไฟและลืมมันจะมีรูปแบบพิเศษสำหรับมัน ไม่ว่าในกรณีใดมันจะไม่เป็นส่วนหนึ่งของไวยากรณ์รวมที่เรียบง่ายที่ฉันกำลังพูดถึง
await
เพียงคำหลักที่คุณจำเป็นต้องหมายถึงการโทรไม่ตรงกันคือ หากคุณรอสายนั้นจะไม่ตรงกัน ถ้าคุณทำไม่ได้การโทรนั้นเป็นแบบเก่าแบบซิงโครนัส (โปรดจำไว้ว่าเราไม่มีไฟและลืมอีกต่อไป)คอมไพเลอร์จะระบุฟังก์ชัน async โดยอัตโนมัติ (เนื่องจากไม่มีการประกาศพิเศษอีกต่อไป) กฎข้อที่ 4 ทำให้ง่ายมากที่จะทำ - ถ้าฟังก์ชั่นมีการ
await
โทรเข้าภายในมันจะเป็นแบบซิงค์
ใช้งานได้ไหม หรือฉันหายไปบางอย่าง ไวยากรณ์ที่เป็นเอกภาพนี้เป็นของเหลวมากขึ้นและสามารถแก้ปัญหาการเข้าทำลายซอมบี้โดยสิ้นเชิง
ตัวอย่างบางส่วน:
// assume this is an async function (has await calls inside)
int CalcRemoteBalanceAsync() { ... }
// assume this is a regular sync function (has no await calls inside)
int CalcRemoteBalance() { ... }
// now let's try all combinations and see what they do:
// this is the common synchronous case - it will block
int b1 = CalcRemoteBalance();
// this is the common asynchronous case - it will not block
int b2 = await CalcRemoteBalanceAsync();
// choosing to call an asynchronous function in a synchronous manner - it will block
// this syntax was used previously for async fire-and-forget, but now it's just synchronous
int b3 = CalcRemoteBalanceAsync();
// strange combination - it will block since it's calling a synchronous function
// it should probably show a compilation warning though
int b4 = await CalcRemoteBalance();
หมายเหตุ: นี่เป็นความต่อเนื่องของการสนทนาที่เกี่ยวข้องที่น่าสนใจใน SO
await
ทันที var task = FooAsync(); Bar(); await task;
คุณสามารถทำสิ่งที่ชอบ ฉันจะทำสิ่งนี้ในข้อเสนอของคุณได้อย่างไร
async
นั่นเป็นมุมมองที่น่าสนใจที่จะพูดน้อยเมื่อคุณกำลังพูดคุยเกี่ยวกับ ฉันคิดว่าเป็นหนึ่งในข้อดีที่ยิ่งใหญ่ของasync
- await
: ช่วยให้คุณสามารถเขียนการดำเนินการแบบอะซิงโครนัสได้อย่างง่ายดาย (ไม่ใช่แค่เพียงเริ่มต้นง่ายรอ A เริ่ม B รอวิธี B) await
และมีอยู่แล้วไวยากรณ์พิเศษว่าสำหรับวัตถุประสงค์นี้มันเรียกว่า