C#: вызов метода [async] без [await] не перехватит его сгенерированное исключение? - PullRequest
0 голосов
/ 06 марта 2020

У меня есть этот фрагмент кода:

class Program
{
    public static async Task ProcessAsync(string s)
    {
        Console.WriteLine("call function");
        if (s == null)
        {
            Console.WriteLine("throw");
            throw new ArgumentNullException("s");
        }
        Console.WriteLine("print");
        await Task.Run(() => Console.WriteLine(s));
        Console.WriteLine("end");
    }
    public static void Main(string[] args)
    {
        try
        {
            ProcessAsync(null);
        }
        catch(Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

Он запускается и печатает:

call function
throw

Хорошо, исключение выдается, но try / catch основной функции не в состоянии перехватить исключение, если я удаляю try / catch, main также не сообщает о необработанном исключении Это очень странно, я гуглил и говорит, что в [await] есть ловушка, но не объясняет, как и почему.

Итак, мой вопрос, почему здесь не обнаруживается исключение, в чем ловушки использования await?

Большое спасибо.

1 Ответ

4 голосов
/ 06 марта 2020

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

Самое простое решение - сделать Main асинхронным:

public static async Task Main(string[] args)
{
  try
  {
    await ProcessAsync(null);
  }
  catch(Exception e)
  {
    Console.WriteLine(e.Message);
  }
}
...