ฉันไม่เข้าใจความแตกต่างระหว่างและTask.Wait
await
ฉันมีบางอย่างที่คล้ายกับฟังก์ชั่นต่อไปนี้ในบริการ 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()
อันไหนดีพอ