C# Academy · บทเรียน

ConfigureAwait และการไหลของข้อยกเว้น

ทำความเข้าใจการจับบริบทและ ConfigureAwait(false) จัดการข้อยกเว้นด้วย await เทียบกับการบล็อก และดู AggregateException กับแนวปฏิบัติที่ดี

บทเรียน 3 จาก 38 ขั้นตอน

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) บอกให้ await ทำอะไร

สรุป

สรุป: ใช้ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. Task/ValueTask และเครื่องจักรสถานะ async (แนวคิด)
  2. ข้อควรระวังของ async: sync-over-async และเดดล็อก
  3. ConfigureAwait และการไหลของข้อยกเว้น
← กลับไปที่ C# Academy