อะไรคือความแตกต่างระหว่าง. Wait () กับ. GetAwaiter (). GetResult ()?


89

วิธีของฉันกลับTaskมา ฉันต้องการรอจนกว่ามันจะเสร็จสิ้น ฉันควรใช้ อะไร.Wait()หรือ.GetAwaiter().GetResult()? อะไรคือความแตกต่างระหว่างพวกเขา?

คำตอบ:


110

ทั้งสองเป็นการรอแบบซิงโครนัสสำหรับผลลัพธ์ของการดำเนินการ (และคุณควรหลีกเลี่ยงสิ่งเหล่านี้ถ้าเป็นไปได้)

ความแตกต่างส่วนใหญ่อยู่ที่การจัดการข้อยกเว้น ด้วยWaitการติดตามสแต็กข้อยกเว้นจะไม่มีการเปลี่ยนแปลงและแสดงถึงสแต็กจริงในช่วงเวลาของข้อยกเว้นดังนั้นหากคุณมีโค้ดส่วนหนึ่งที่รันบนเธรดพูลเธรดคุณจะมีสแต็กเช่น

ThreadPoolThread.RunTask
YourCode.SomeWork

ในทางกลับกัน.GetAwaiter().GetResult()จะทำซ้ำการติดตามสแต็กเพื่อนำบริบทอะซิงโครนัสทั้งหมดมาพิจารณาโดยไม่สนใจว่าบางส่วนของโค้ดดำเนินการบนเธรด UI และบางส่วนบนเธรด ThreadPool และบางส่วนเป็น I / O แบบอะซิงโครนัส ดังนั้นการติดตามสแต็กของคุณจะสะท้อนถึงขั้นตอนที่เหมือนซิงโครนัสผ่านโค้ดของคุณ :

TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork

สิ่งนี้มีแนวโน้มที่จะทำให้การติดตามสแต็คข้อยกเว้นมีประโยชน์มากกว่าอย่างมากพูดอย่างน้อยที่สุด คุณสามารถดูตำแหน่งที่YourCode.SomeWorkถูกเรียกในบริบทของแอปพลิเคชันของคุณแทนที่จะเป็น "วิธีการทำงานจริง"

ตัวอย่างวิธีการทำงานนี้อยู่ในแหล่งอ้างอิง (แน่นอนว่าไม่ใช่สัญญา)


6
Task.GetAwaiter () ส่งกลับTaskAwaiter อย่างไรก็ตามเอกสารสำหรับTaskAwaiter.GetResult ()ให้คำแนะนำว่า: "API นี้รองรับโครงสร้างพื้นฐานของผลิตภัณฑ์และไม่ได้ตั้งใจให้ใช้โดยตรงจากรหัสของคุณ" คุณสามารถแสดงความคิดเห็น?
DavidRR

24
@DavidRR ทั้งหมดTaskAwaiterคือรายละเอียดการใช้งาน ในทางตรงกันข้ามกลไก awaitable / awaiter เป็นเอกสารและการใช้เป็ดพิมพ์ - GetAwaiterคือการawaitเป็นGetEnumeratorคือการforeachหรือคือการDispose usingทั้งหมดนี้ถูกกำหนดไว้ในข้อกำหนด C # โดยไม่คำนึงถึงตัวรอที่จะใช้ - โปรดทราบว่าTask.GetAwaiter"มีไว้สำหรับการใช้คอมไพเลอร์แทนที่จะใช้ในโค้ดแอ็พพลิเคชัน" แต่ประเด็นคือการใช้งานที่ตั้งใจไว้คือการทำawaitไม่ใช่Wait()หรือGetAwaiter().GetResult()- แต่GetResultให้กองที่ดีกว่าหากคุณต้องการ
Luaan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.