ฉันไม่เข้าใจความแตกต่างระหว่างและTask.Waitawait
ฉันมีบางอย่างที่คล้ายกับฟังก์ชั่นต่อไปนี้ในบริการ ASP.NET WebAPI:
public class TestController : ApiController
{
public static async Task<string> Foo()
{
await Task.Delay(1).ConfigureAwait(false);
return "";
}
public async static Task<string> Bar()
{
return await Foo();
}
public async static Task<string> Ros()
{
return await Bar();
}
// GET api/test
public IEnumerable<string> Get()
{
Task.WaitAll(Enumerable.Range(0, 10).Select(x => Ros()).ToArray());
return new string[] { "value1", "value2" }; // This will never execute
}
}
ที่ไหนGetจะหยุดชะงัก
อะไรทำให้เกิดสิ่งนี้ ทำไมไม่ได้นี้เป็นสาเหตุปัญหาเมื่อผมใช้รอการปิดกั้นมากกว่าawait Task.Delay?
Task.Delay(1).Wait()Thread.Sleep(1000)เป็นพื้นสิ่งเดียวที่แน่นอนเป็น ในรหัสการผลิตจริงมันไม่ค่อยเหมาะสม
WaitAllทำให้เกิดการหยุดชะงัก ดูลิงก์ไปยังบล็อกของฉันในคำตอบของฉันสำหรับรายละเอียดเพิ่มเติม คุณควรใช้await Task.WhenAllแทน
ConfigureAwait(false)การโทรเพียงครั้งเดียวไปยังBarหรือRosจะไม่หยุดชะงัก แต่เนื่องจากคุณมีการนับจำนวนที่สร้างมากกว่าหนึ่งรายการแล้วรอทุกสายแถบแรกจะหยุดชะงักวินาที หากคุณawait Task.WhenAllแทนที่จะรองานทั้งหมดเพื่อที่คุณจะไม่ได้ปิดกั้นบริบท ASP คุณจะเห็นวิธีการส่งคืนตามปกติ
.ConfigureAwait(false) ตลอดทางขึ้นต้นไม้จนกว่าคุณจะปิดกั้นว่าไม่มีอะไรวิธีที่จะเคยพยายามที่จะได้รับกลับไปบริบทหลัก ที่จะทำงาน ตัวเลือกอื่นคือการหมุนบริบทการซิงโครไนซ์ภายใน ลิงค์ หากคุณใส่Task.WhenAllในAsyncPump.Runได้อย่างมีประสิทธิภาพจะป้องกันในสิ่งที่ทั้งโดยที่คุณไม่ต้องไปConfigureAwaitที่ใดก็ได้ แต่ที่อาจเป็นทางออกที่มากเกินไปที่ซับซ้อน
Task.Delay(1).Wait()อันไหนดีพอ