การจับ Exception จาก Task ที่ไม่ได้ catch ไว้ใน C#

slash-blog-c-exception

ในการเขียนโปรแกรมภาษา C# ให้ทำงานในเธรด (thread) ถ้าเกิดเอ็กเซ็พชัน (exception) ขึ้น จะตรวจสอบได้จาก Task.IsFaulted() ซึ่งเราต้องเก็บตัวแปรทาสค์ (task) ไว้

แต่การเขียนให้ตรวจสอบสถานะของทาสค์นั้น อาจไม่สะดวกและทำให้โปรแกรมซับซ้อน ใน C# 5.0 ขึ้นไปที่รองรับการใช้ async/await จะทำให้เขียนได้ง่ายขึ้นมาก โดยจับ exception เสมือนว่าทำงานแบบ synchronous ได้เลยดังนี้

try
{
    var task = Task.Factory.StartNew<StateObject>(() => { /* action */ });
    await task;
}
catch (Exception e)
{
    /* error handling */
}

แต่ถ้าใช้ C# 4.0 ลงมา จะใช้การเชื่อมต่อทาสค์เข้าด้วยกันโดยระบุว่าจะจับ exception เมื่อมันเกิดขึ้นเท่านั้นได้ดังนี้

var task = Task.Factory
    .StartNew<StateObject>(() => { /* action */ })
    .ContinueWith(t => {
        t.Exception.Flatten().Handle(e => {
            /* error handling */
            return true; // true = handled ourselves
        });
    }, TaskContinuationOptions.OnlyOnFaulted);

โปรแกรมจะเข้าไปที่ /* error handling */ เมื่อเกิด Faulted หรือเกิด exception เท่านั้น จึงทำให้โค้ดการทำงานปกติกับการจัดการข้อผิดพลาดอยู่ด้วยกัน ทำให้แก้ไขและมองภาพรวมได้ง่ายขึ้น

ที่มา:

สแลช (Slash)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s