Попробуйте Catch за пределами: жду Task.Run(()

Попробуйте поймать за пределами: await Task.Run(() => иметь смысл или просто использовать их только внутри ожидающих?

private async void Test()
{
     try
     {
         await Task.Run(() =>
         {
             try
             {
                  DoingSomething();
             }
             catch (Exception ex)
             {
                  log.Error(ex.Message);
             }
         });
      }
      catch (Exception ex)
      {
          log.Error(ex.Message);
      }
}

Ответ 1

Если вы обрабатываете Exception внутри делегата (в вашем случае только для целей ведения журнала), await не приведет к возникновению исключения в обычных обстоятельствах. Это должно быть хорошо.

private async Task Test()
{
         await Task.Run(() =>
         {
             try
             {
                  DoingSomething();
             }
             catch (Exception ex)
             {
                  log.Error(ex.Message);
             }
         });

}

Однако, поскольку вы await ing Task, скорее всего, в методе Test будет несколько DoSomethingElse, на которые может повлиять результат Task - и в этом случае также имеет смысл иметь try/catch вокруг await.

private async Task Test()
{
     try
     {
         await Task.Run(() =>
         {
             try
             {
                  DoingSomething();
             }
             catch (SomeSpecialException spex)
             {
                  // it is OK to have this exception
                  log.Error(ex.Message);
             }
         });

         DoSomethingElse(); // does not run when unexpected exception occurs.
      }
      catch (Exception ex)
      {
          // Here we are also running on captured SynchronizationContext
          // So, can update UI to show error ....
      }
}

Ответ 2

Если делегат, которому вы перешли на Task.Run, возникает исключение, вы можете поймать его вне Task.Run, когда вы await возвратили задание.

Вы не должны думать о await, как будто это был блок. Нет такой вещи, как "внутри ожидания". Вместо этого подумайте await как о том, что оператор принимает один аргумент (в этом случае Task возвращается Task.Run). Task.Run будет перехватывать исключения из своего делегата и помещать их в возвращаемый Task; await будет распространять это исключение.

Ответ 3

Вы также можете добавить try catch к внешнему коду. Компилятор выполнит секцию catch, когда исключение произойдет во время асинхронного вызова. Вот более подробная информация, почему вам нужно попытаться поймать в ожидании http://msdn.microsoft.com/en-us/library/vstudio/0yd65esw.aspx посмотреть Исключения в методах Async