ConfigureAwait และการไหลของข้อยกเว้น
ทำความเข้าใจการจับบริบทและ ConfigureAwait(false) จัดการข้อยกเว้นด้วย await เทียบกับการบล็อก และดู AggregateException กับแนวปฏิบัติที่ดี
ConfigureAwait และการไหลของข้อยกเว้น เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 3 บทเรียน
บริบทและข้อยกเว้น
เป้าหมาย:
- เข้าใจว่าการเก็บบริบทคืออะไร
- รู้ว่าเมื่อใดควรใช้ ConfigureAwait(false)
- เข้าใจว่าข้อยกเว้นไหลผ่านการทำงานของ await อย่างไร
- เข้าใจว่าเหตุใดการหยุดรอจึงนำไปสู่AggregateException
แนวทางปฏิบัติที่ดีสำหรับไลบรารี
เมธอดของไลบรารีควรใช้ ConfigureAwait(false) เพื่อหลีกเลี่ยงการกลับไปทำงานต่อในบริบท UI/เว็บที่ไลบรารีไม่ได้เป็นเจ้าของ
using System;
using System.Threading.Tasks;
public static class NetLib
{
// Library code should not assume a UI context. Use ConfigureAwait(false).
public static async Task<string> FetchAsync()
{
await Task.Delay(100).ConfigureAwait(false); // do not capture context
return "payload";
}
}
public class Program
{
public static void Main(string[] args)
{
// Console apps typically have no SynchronizationContext; this still runs fine.
string s = NetLib.FetchAsync().GetAwaiter().GetResult();
Console.WriteLine("Got: " + s);
}
}
กฎของบริบท
การเก็บบริบท:
- โดยค่าเริ่มต้น await จะพยายามกลับไปทำงานต่อในบริบทที่เก็บไว้ เช่น UI/ASP.NET
- ConfigureAwait(false) หมายความว่าไม่ต้องเก็บบริบท ให้ทำงานต่อบนกลุ่มเธรด
- ช่วยหลีกเลี่ยงภาวะติดตายเมื่อผู้เรียกหยุดรอเธรดของบริบท
- โค้ด UI อาจต้องใช้บริบทเพื่ออัปเดตตัวควบคุม ส่วนโค้ดไลบรารีโดยทั่วไปไม่ควรทำเช่นนั้น
การรอและข้อยกเว้น
เมื่อใช้ await ข้อยกเว้นจะส่งต่อมาเป็นชนิดข้อยกเว้นเดิม จึงดักจับตามปกติได้
using System;
using System.Threading.Tasks;
public class Program
{
static async Task<string> BoomAsync()
{
await Task.Delay(50);
throw new InvalidOperationException("boom");
}
public static void Main(string[] args)
{
// With await (inside async), exceptions rethrow as the original type.
try
{
string r = BoomAsync().GetAwaiter().GetResult(); // emulate await in Main
Console.WriteLine(r);
}
catch (InvalidOperationException ex)
{
Console.WriteLine("Caught: " + ex.GetType().Name + " - " + ex.Message);
}
}
}
การบล็อกและข้อผิดพลาด
การบล็อกด้วย .Result หรือ .Wait() จะรวมข้อผิดพลาดไว้ใน AggregateException ควรใช้ await เพื่อให้การส่งต่อข้อผิดพลาดชัดเจนกว่า
using System;
using System.Threading.Tasks;
public class Program
{
static async Task<int> FailsAsync()
{
await Task.Delay(30);
throw new ArgumentException("bad arg");
}
public static void Main(string[] args)
{
try
{
// Blocking with .Result wraps the exception into AggregateException
int x = FailsAsync().Result;
Console.WriteLine(x);
}
catch (AggregateException ae)
{
Exception inner = ae.InnerException;
Console.WriteLine("AggregateException -> " + (inner == null ? "null" : inner.GetType().Name));
}
}
}
แนวทางปฏิบัติที่ดี
แนวทาง:
- ในไลบรารี ให้ใช้ ConfigureAwait(false)
- ใน UI/เว็บ ให้ใช้ await บนเธรดผู้เรียกเมื่อต้องใช้บริบท
- หลีกเลี่ยง .Result/.Wait() และดักจับข้อยกเว้นเดิมด้วย await
- ใช้ Log และโยนข้อยกเว้นซ้ำพร้อมข้อความที่คำนึงถึงบริบทเมื่อจำเป็น
การทำงานของ ConfigureAwait
สรุป
สรุป: ใช้ ConfigureAwait(false) ในไลบรารี ส่วนโค้ด UI/เว็บควรตัดสินใจเองว่าเมื่อใดจำเป็นต้องใช้บริบท ควรใช้ await เพื่อให้การส่งต่อข้อยกเว้นชัดเจน การหยุดรอจะรวมข้อผิดพลาดและเสี่ยงต่อภาวะติดตาย
เรียนรู้ C# ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 93
- บทเรียน
- 346
คำถามที่พบบ่อย
บทเรียน “ConfigureAwait และการไหลของข้อยกเว้น” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ConfigureAwait และการไหลของข้อยกเว้น” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ConfigureAwait และการไหลของข้อยกเว้น”
ทำความเข้าใจการจับบริบทและ ConfigureAwait(false) จัดการข้อยกเว้นด้วย await เทียบกับการบล็อก และดู AggregateException กับแนวปฏิบัติที่ดี คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 3 บทเรียน
บทเรียน “ConfigureAwait และการไหลของข้อยกเว้น” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Task/ValueTask และเครื่องจักรสถานะ async (แนวคิด)
- ข้อควรระวังของ async: sync-over-async และเดดล็อก
- ConfigureAwait และการไหลของข้อยกเว้น