วิธีของฉันกลับTask
มา ฉันต้องการรอจนกว่ามันจะเสร็จสิ้น ฉันควรใช้
อะไร.Wait()
หรือ.GetAwaiter().GetResult()
? อะไรคือความแตกต่างระหว่างพวกเขา?
วิธีของฉันกลับTask
มา ฉันต้องการรอจนกว่ามันจะเสร็จสิ้น ฉันควรใช้
อะไร.Wait()
หรือ.GetAwaiter().GetResult()
? อะไรคือความแตกต่างระหว่างพวกเขา?
คำตอบ:
ทั้งสองเป็นการรอแบบซิงโครนัสสำหรับผลลัพธ์ของการดำเนินการ (และคุณควรหลีกเลี่ยงสิ่งเหล่านี้ถ้าเป็นไปได้)
ความแตกต่างส่วนใหญ่อยู่ที่การจัดการข้อยกเว้น ด้วยWait
การติดตามสแต็กข้อยกเว้นจะไม่มีการเปลี่ยนแปลงและแสดงถึงสแต็กจริงในช่วงเวลาของข้อยกเว้นดังนั้นหากคุณมีโค้ดส่วนหนึ่งที่รันบนเธรดพูลเธรดคุณจะมีสแต็กเช่น
ThreadPoolThread.RunTask
YourCode.SomeWork
ในทางกลับกัน.GetAwaiter().GetResult()
จะทำซ้ำการติดตามสแต็กเพื่อนำบริบทอะซิงโครนัสทั้งหมดมาพิจารณาโดยไม่สนใจว่าบางส่วนของโค้ดดำเนินการบนเธรด UI และบางส่วนบนเธรด ThreadPool และบางส่วนเป็น I / O แบบอะซิงโครนัส ดังนั้นการติดตามสแต็กของคุณจะสะท้อนถึงขั้นตอนที่เหมือนซิงโครนัสผ่านโค้ดของคุณ :
TheSyncMethodThatWaitsForTheAsyncMethod
YourCode.SomeAsyncMethod
SomeAsync
YourCode.SomeWork
สิ่งนี้มีแนวโน้มที่จะทำให้การติดตามสแต็คข้อยกเว้นมีประโยชน์มากกว่าอย่างมากพูดอย่างน้อยที่สุด คุณสามารถดูตำแหน่งที่YourCode.SomeWork
ถูกเรียกในบริบทของแอปพลิเคชันของคุณแทนที่จะเป็น "วิธีการทำงานจริง"
ตัวอย่างวิธีการทำงานนี้อยู่ในแหล่งอ้างอิง (แน่นอนว่าไม่ใช่สัญญา)
TaskAwaiter
คือรายละเอียดการใช้งาน ในทางตรงกันข้ามกลไก awaitable / awaiter เป็นเอกสารและการใช้เป็ดพิมพ์ - GetAwaiter
คือการawait
เป็นGetEnumerator
คือการforeach
หรือคือการDispose
using
ทั้งหมดนี้ถูกกำหนดไว้ในข้อกำหนด C # โดยไม่คำนึงถึงตัวรอที่จะใช้ - โปรดทราบว่าTask.GetAwaiter
"มีไว้สำหรับการใช้คอมไพเลอร์แทนที่จะใช้ในโค้ดแอ็พพลิเคชัน" แต่ประเด็นคือการใช้งานที่ตั้งใจไว้คือการทำawait
ไม่ใช่Wait()
หรือGetAwaiter().GetResult()
- แต่GetResult
ให้กองที่ดีกว่าหากคุณต้องการ