สะดุดกับโพสต์นี้ที่พูดถึงเกี่ยวกับการทำคำขอเว็บ async
ตอนนี้ความเรียบง่ายกันถ้าในโลกแห่งความจริงสิ่งที่คุณต้องทำคือการขอ async และรอให้มันอยู่ในบรรทัดถัดไปนั่นไม่เหมือนกับการโทรแบบซิงค์ในตอนแรกใช่ไหม
สะดุดกับโพสต์นี้ที่พูดถึงเกี่ยวกับการทำคำขอเว็บ async
ตอนนี้ความเรียบง่ายกันถ้าในโลกแห่งความจริงสิ่งที่คุณต้องทำคือการขอ async และรอให้มันอยู่ในบรรทัดถัดไปนั่นไม่เหมือนกับการโทรแบบซิงค์ในตอนแรกใช่ไหม
คำตอบ:
ไม่async + await != sync
เพราะความต่อเนื่อง
จาก MSDN 'การเขียนโปรแกรมแบบอะซิงโครนัสกับ Async และ Await (C # และ Visual Basic)'
วิธีการแบบอะซิงก์มีจุดประสงค์เพื่อการดำเนินการที่ไม่ปิดกั้น นิพจน์ที่รออยู่ในเมธอด async จะไม่บล็อกเธรดปัจจุบันในขณะที่งานที่รออยู่กำลังทำงานอยู่ แต่นิพจน์จะลงทะเบียนส่วนที่เหลือของเมธอดเป็นความต่อเนื่องและส่งกลับการควบคุมไปยังผู้เรียกของเมธอด asyncแทน
ตัวอย่างเช่นการดำเนินการ async จะไม่บล็อกเธรด UI และSome TextBox.Text
จะได้รับการอัปเดตหลังจากการดาวน์โหลดเสร็จสิ้น
private async void OnButtonClick()
{
SomeTextBox.Text = await new WebClient().DownloadStringTaskAsync("http://stackoverflow.com/");
}
Console.WriteLine(await GetStringOverNetwork());
อะไร ถ้าคุณต้องการเอาต์พุตของการเรียกใช้แบบอะซิงโครนัส? โปรแกรมจะบล็อกการเข้าถึงครั้งแรกหรือไม่แม้ว่าเธรดสามารถดำเนินการต่อได้หรือไม่
ไม่มันไม่เหมือนกัน
async
บล็อคโค้ดของคุณกำลังรอการawait
โทรกลับเพื่อดำเนินการต่ออย่างไรก็ตามแอปพลิเคชั่นที่เหลือของคุณไม่รอและยังสามารถทำงานต่อได้ตามปกติ
ในทางตรงกันข้ามการโทรแบบซิงโครนัสจะทำให้ทั้งแอปพลิเคชันหรือเธรดของคุณรอจนกว่าโค้ดจะเสร็จสิ้นเพื่อดำเนินการต่อด้วยสิ่งอื่น
โปรดอนุญาตให้ฉันอธิบายสิ่งต่าง ๆ ที่เกี่ยวข้องกับ async / รอคอย
เมื่อพบการรอคอยเครื่องสถานะพื้นฐานช่วยให้สามารถส่งคืนการควบคุมได้ทันที จากนั้นเมื่อการเรียกที่รอเสร็จสมบูรณ์เครื่องสถานะพื้นฐานจะอนุญาตให้การดำเนินการเพื่อดำเนินการที่บรรทัดหลังจากการโทรที่รอ
ดังนั้นบล็อก async จึงไม่ถูกบล็อกหรือไม่รอสายที่รอให้เสร็จ การควบคุมจะถูกส่งคืนทันทีเมื่อพบคำสั่ง await
เครื่องสถานะพื้นฐานเป็นส่วนหนึ่งของ "เวทย์มนตร์" ที่อยู่เบื้องหลังการใช้ async / รอที่ไม่ได้ใช้งานและพลาด
ฉันสะดุดกับคำถามเดียวกันนี้ในใจ แต่หลังจากอ่านคำตอบแล้วคำถามก็ดูเหมือนจะยังคงสับสนโดยอ้างอิงถึง "เวทมนตร์ภายใต้ประทุน"
จากการเขียนโปรแกรม Asynchronousดังกล่าวข้างต้น :
async
คำหลักที่จะเปลี่ยนวิธีเป็นวิธี async ซึ่งจะช่วยให้คุณสามารถใช้await
คำหลักในร่างกายของตน- เมื่อ
await
คำหลักถูกนำไปใช้มันจะระงับวิธีการโทรและให้การควบคุมกลับไปยังผู้โทรจนกว่างานที่รอจะเสร็จสมบูรณ์await
สามารถใช้ได้ภายในasync
เมธอดเท่านั้น
บริบทที่พบawait
ถูกบล็อกหรือไม่
ส่วนที่เหลือของแอปพลิเคชันบล็อกawait
หรือไม่
ขึ้นอยู่กับการเขียนใบสมัครของคุณ หากเป็นชุดของawait
งานที่ต้องทำตามลำดับที่เปิดตัวตามลำดับในบริบทเดียวกัน (ดู: การพยายามทำความเข้าใจพฤติกรรมการทำงานของ async / await )
await asyncCall1();
await asyncCall2(); // waits for asyncCall1() to complete
วิธีนี้แต่ละคนawait
จะบล็อกการวางไข่ของคนต่อไป
ในทางกลับกันงานที่ต้องพึ่งพากันที่เปิดตัวในแบบขนานจะทำงานในแบบคู่ขนานและบริบทจะบล็อกเฉพาะที่การตอบสนองเท่านั้น await
:
Task<int> t1 = asyncCall1();
Task<string> t2 = asyncCall2(); // runs in parallel with asyncCall1()
int val = await t1;
string str = await t2; // waits for asyncCall1() to complete
โดยทั่วไปแล้วการawait
ดำเนินการให้ผลตอบแทนกับบริบทด้านนอกจากที่บริบทปัจจุบันเรียกว่า อย่างไรก็ตามถ้าบริบทรอบนอกกำลังรอกระแสอยู่มันก็เหมือนกับลำดับawait
ที่อยู่ในบริบทเดียวกัน
ดังนั้นเพื่อที่จะเก็บเกี่ยวasync
ผลประโยชน์อย่างใดอย่างหนึ่งความต้องการในการออกแบบการประยุกต์ใช้ในการทำงานบริบทหลายขนาน (UI ข้อมูลลูกค้า ฯลฯ ) แล้วawait
ในการดำเนินการที่อัตราผลตอบแทนบริบทแวดล้อมอื่น ๆ await
เพื่อให้แอพลิเคชันทั้งหมดจะไม่ปิดกั้นในแต่ละ