2018年8月19日 星期日

【C#】Exception handling while multi-threading

static void Main(string[] args)
{
    
    try
    {
        Task.Run(() =>
        {
            throw new Exception("occurs in task");
        });
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    Console.ReadLine();
}
執行上述程式你會發現 cmd 沒寫 ex.Message,原因是 exception handling 是 per thread 的,也就是說在外緒發生的 exception 主緒 catch 不到

這有幾個解
1. 把 try catch 改包在裡面(這個最簡單)
static void Main(string[] args)
{
    Task.Run(() =>
    {
        try
        {
            throw new Exception("occurs in task");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    });
    Console.ReadLine();
}

2. 靠 TaskStatus 判斷執行結果並挖掘其中的錯誤
var t = Task.Run(() =>
{
    throw new Exception("occurs in task");
})
.ContinueWith((result) =>
{
    if (result.Status == TaskStatus.Faulted)
    {
        foreach (var ex in result.Exception.InnerExceptions)
        {
            Console.WriteLine(ex.Message);
        }
    }
});

3. 使用 await
static void Main(string[] args)
{
    FooAsync();
    Console.ReadLine();
}

private static async Task FooAsync()
{
    try
    {
        await Task.Run(() =>
        {
            throw new Exception("occurs in task");
        });
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

沒有留言:

張貼留言