web-dev-qa-db-ja.com

非同期メソッドで例外をスローする方法(Task.FromException)

.NET 4.6以降、FromExceptionオブジェクトに新しいメソッドTaskがあり、asyncで例外をスローする最善の方法は何なのか疑問に思いました方法

ここに2つの例があります:

internal class Program
{
    public static void Main(string[] args)
    {
        MainAsync().Wait();
    }

    private static async Task MainAsync()
    {
        try
        {
            Program p = new Program();
            string x = await p.GetTest1(@"C:\temp1");
        }
        catch (Exception e)
        {
            // Do something here
        }
    }

    // Using the new FromException method
    private Task<string> GetTest1(string filePath)
    {
        if (!Directory.Exists(filePath))
        {
            return Task.FromException<string>(new DirectoryNotFoundException("Invalid directory name."));
        }
        return Task.FromResult(filePath);
    }

    // Using the normal throw keyword
    private Task<string> GetTest2(string filePath)
    {
        if (!Directory.Exists(filePath))
        {
             throw new DirectoryNotFoundException("Invalid directory name.");
        }
        return Task.FromResult(filePath);
    }
}
12
Bidou

GetTest1()と_GetTest2_の動作には違いがあります。

GetTest1()は、メソッドが呼び出されても例外をスローしません。代わりに、_Task<string>_を返します。タスクが待機するまで例外はスローされません(タスクを検査して、例外をスローせずに成功したかどうかを確認することもできます)。

対照的に、GetTest2()は、_Task<string>_を返すことなく、呼び出されたときにすぐに例外をスローします。

どちらを使用するかは、希望する動作に依存すると思います。 GetTest()タスクの束があり、並行して実行したいが、成功したタスクの実行を続行したい場合は、各タスクの結果を検査できる_Task.FromException_を使用します。それに応じて行動します。対照的に、リスト内の例外で実行を続行したくない場合は、例外をスローするだけです。

10
Stewart_R