สะดุดกับโพสต์นี้ที่พูดถึงเกี่ยวกับการทำคำขอเว็บ 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เพื่อให้แอพลิเคชันทั้งหมดจะไม่ปิดกั้นในแต่ละ