2015-06-06 4 views
6
образец

Кода:Бросив исключение из Task.Run отображает «Не обрабатывался от кода пользователя» Сообщение

using System; 
using System.Threading.Tasks; 

public class Program 
{ 
    public static void Main() 
    { 
     Console.WriteLine("Start"); 
     Foo f = new Foo(); 
     f.FooAsync(); 
    } 

    public class Foo 
    { 
     public async void FooAsync() 
     { 
      try 
      { 
       await Task.Run(() => 
       { 
        Console.WriteLine("Throwing"); 
        throw new Exception(); 
       }); 
      } 
      catch (Exception) 
      { 
       Console.WriteLine("Caught"); 
      } 
     } 
    } 
} 

Приведенных выше код при запуске из C# скрипки или с консоли на моих гравюрах ПК:

Start 
Throwing 
Caught 

C# Fiddle Example

Однако, когда я запускаю его из Visual Studio (F5 в режиме отладки), я получаю следующее сообщение:

Exception Picture

Я не понимаю, почему я получил сообщение «не обрабатывался в пользовательском коде» из Visual Studio, хотя запуск его с консоли или скрипта C# прекрасен. Мне что-то не хватает?

UPDATE

Я попытался ожидание задачи f.FooAsync().Wait(); в Main, но исключение по-прежнему сообщается как необработанное (то же самое сообщение об ошибке).

+1

Код в порядке, это неправильные настройки вашего отладчика. Нажмите ссылку «Открыть настройки исключения», снимите флажок «Бросить». Если вы включили его намеренно, просто нажмите «Продолжить». –

+0

@ HansPassant: Спасибо. Здесь я нашел [подробнее об этой проблеме] (http://stackoverflow.com/a/16925282/906773). –

ответ

8

Во-первых, что особенного в этом исключением является то, что он будучи выброшен из Task.Run и для этой сферы, исключение действительно не обрабатывается пользовательским кодом.

Фреймворк ловит и сохраняет исключение в возвращаемой задаче для обработки позже, если вы этого не сделаете, это незаметное исключение задачи (которое в .NET 4.0 могло бы повредить приложение).

Проблема здесь в функции «Включить только мой код» в настройках. Когда функция включена, отладчик прерывает исключения, когда вы оставляете код пользователя и вводите фрейм-код, и в этот момент исключение действительно не обрабатывалось.

Если вы отключите эту функцию, отладчик не нарушит это исключение, поскольку оно будет следовать вашему коду в фреймворк и увидеть, что исключение обрабатывается и сохраняется в задаче. Исключение будет затем повторно выбрано, когда вы выполните await задачу и будете обрабатываться вашим кодом.


Поскольку обработка, что на самом деле имеет значение это один делается в рамках, это еще более простой пример:

public static void Main() 
{ 
    Task.Run(() => 
    { 
     throw new Exception(); 
    }); 
    Console.ReadLine(); 
} 

С «Enable Just My Code» включен отладчик разобьет на исключение, без него отладчик не будет.

+1

Я согласен, что это правильный ответ. –

Смежные вопросы