ฉันพบแนวทางปฏิบัติที่ดีที่สุดสำหรับการเขียนโปรแกรมแบบอะซิงโครนัสโดยใช้ c # async
/ await
คำหลัก (ฉันเพิ่งเริ่มใช้ c # 5.0)
หนึ่งในคำแนะนำที่ได้รับมีดังต่อไปนี้:
ความเสถียร: รู้บริบทการซิงโครไนซ์ของคุณ
... บริบทการซิงโครไนซ์บางส่วนไม่ได้ reentrant และ single-threaded ซึ่งหมายความว่าสามารถทำงานได้เพียงหน่วยเดียวในบริบทในช่วงเวลาที่กำหนด ตัวอย่างนี้คือเธรด UI ของ Windows หรือบริบทการร้องขอ ASP.NET ในบริบทการซิงโครไนซ์แบบเธรดเดี่ยวเหล่านี้คุณสามารถหยุดชะงักได้โดยง่าย หากคุณวางภารกิจจากบริบทเธรดเดียวให้รองานนั้นในบริบทรหัสรอของคุณอาจบล็อกงานเบื้องหลัง
public ActionResult ActionAsync()
{
// DEADLOCK: this blocks on the async task
var data = GetDataAsync().Result;
return View(data);
}
private async Task<string> GetDataAsync()
{
// a very simple async method
var result = await MyWebService.GetDataAsync();
return result.ToString();
}
ถ้าฉันพยายามที่จะแยกมันออกด้วยตัวเองเธรดหลักจะปรากฏเป็นเธรดใหม่MyWebService.GetDataAsync();
แต่เนื่องจากเธรดหลักรออยู่ที่นั่นจึงรอผลลัพธ์ในGetDataAsync().Result
. ในขณะเดียวกันบอกว่าข้อมูลพร้อมแล้ว เหตุใดเธรดหลักจึงไม่ดำเนินการต่อเป็นตรรกะความต่อเนื่องและส่งคืนผลลัพธ์สตริงจากGetDataAsync()
?
ใครช่วยอธิบายหน่อยได้ไหมว่าทำไมถึงเกิดการชะงักงันในตัวอย่างด้านบน ฉันไม่รู้เลยว่าปัญหาคืออะไร ...