Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to throw an exception in an async method (Task.FromException)

I just discovered that, since .NET 4.6, there is a new method FromException on the Task object, and I was wondering what was the best way to throw exceptions in an async method.

Here are two examples:

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);
    }
}
like image 669
Bidou Avatar asked Jan 19 '17 07:01

Bidou


1 Answers

There is a difference in behaviour between GetTest1() and GetTest2.

GetTest1() will not throw the exception when the method is called. Instead it returns a Task<string>. The exception will not be thrown until that task is awaited (we could also have chosen to inspect the task to see if succeeded without ever throwing the exception).

In contrast GetTest2() throws the exception immediately when called without ever returning the Task<string>

I guess which one you use would depend on the desired behaviour. If I had a bunch of GetTest() tasks I wanted to run in parallel and I wanted execution to continue for those tasks that succeeded then I would use Task.FromException which allows me to inspect the results of each Task and act accordingly. In contrast, if any Exception in the list meant I didn't want execution to continue I would likely just throw the Exception.

like image 132
Stewart_R Avatar answered Oct 23 '22 10:10

Stewart_R