2017-01-19 6 views
3

Я только что обнаружил, что с .NET 4.6 появился новый метод FromException на объекте Task, и мне было интересно, что было лучшим способом отбросить исключения в async методКак сделать исключение в async-методе (Task.FromException)

Вот два примера:

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); 
    } 
} 
+1

Лучший способ бросить исключения в методе 'async' -' throw'. Однако ни один из ваших примеров не является методом async. –

ответ

3

Существует разница в поведении между GetTest1() и GetTest2.

GetTest1() не будет генерировать исключение при вызове метода. Вместо этого он возвращает Task<string>. Исключение не будет выбрано до тех пор, пока эта задача не будет ожидаться (мы также могли бы выбрать, чтобы проверить задачу, чтобы убедиться, что она удалась, даже не выбросив исключение).

В отличие GetTest2() бросает исключение сразу при вызове никогда не возвращая Task<string>

Я предполагаю, какой вы используете, будет зависеть от желаемого поведения. Если бы у меня была группа GetTest() задач, которые я хотел запустить параллельно, и я хотел, чтобы выполнение продолжалось для тех задач, которые преуспели, я бы использовал Task.FromException, что позволяет мне проверять результаты каждой задачи и действовать соответствующим образом. В отличие от этого, если какое-либо исключение в списке означает, что я не хотел, чтобы исполнение продолжалось, я бы просто выбросил исключение.

+0

Этот последний абзац не имеет смысла. 'Task.FromException' не должно использоваться в методах async. –

+0

@ StephenCleary удалил оскорбительный пункт - спасибо, указав его –

+0

@ Stephen Cleary Почему бы и нет? (! Directory.Exists (Filepath)): Например, 'частный асинхронном Task GetTest3 (строка Filepath) { если { возвращения ждут Task.FromException (новый DirectoryNotFoundException() "недопустимое имя каталога."); } } } ' – Bidou