Je viens de découvrir que depuis .NET 4.6, il existe une nouvelle méthode FromException
sur l'objet Task
, et je me demandais quelle était la meilleure façon de lever des exceptions dans un async
méthode
Voici deux exemples:
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);
}
}
Il existe une différence de comportement entre GetTest1()
et GetTest2
.
GetTest1()
ne lèvera pas l'exception lorsque la méthode est appelée. Au lieu de cela, il renvoie un Task<string>
. L'exception ne sera pas levée tant que cette tâche n'est pas attendue (nous aurions également pu choisir d'inspecter la tâche pour voir si elle a réussi sans jamais lever l'exception).
En revanche, GetTest2()
lève l'exception immédiatement lorsqu'elle est appelée sans jamais renvoyer le Task<string>
Je suppose que celui que vous utiliserez dépendrait du comportement souhaité. Si j'avais un tas de tâches GetTest()
que je voulais exécuter en parallèle et que je voulais que l'exécution se poursuive pour les tâches qui ont réussi, j'utiliserais Task.FromException
Qui me permet d'inspecter les résultats de chaque Tâchez et agissez en conséquence. En revanche, si une exception dans la liste signifiait que je ne voulais pas que l'exécution se poursuive, je lèverais probablement l'exception.