Reputation: 7668
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);
}
}
Upvotes: 17
Views: 27888
Reputation: 14485
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.
Upvotes: 23