2012-01-26 2 views
6

Visual Studio имеет определенную функцию, облегчающую отладку необработанных исключений: она останавливается на нарушающей строке кода и показывает исключение.Могу ли я, чтобы Visual Studio остановилась на необработанных исключениях внутри кода задачи?

Похоже, что класс Task сконструирован таким образом, что эта функция всегда подавляется: она улавливает каждое исключение, а затем вызывает другое исключение, когда задание Wait ed или finalized.

Я знаю, что я могу остановить его на исключениях первого шанса, но это не всегда помогает: представьте, что перед обработанным случаем происходит несколько обработанных исключений одного типа. В этом случае VS будет останавливаться на каждом не проблематичном исключении в дополнение к тому, что действительно вызывает проблему.

Еще одна альтернатива является еще менее приемлемой: просто глядя на трассировку стека InnerException: это означает, что, хотя я знаю, какая строка вызвала исключение, я не могу получить доступ к каким-либо ее локальным состояниям, как если бы программа была на самом деле остановился.

Могу ли я как-то получить лучшее из обоих миров, используя класс Task, но не имея необходимости жить с набором функций отладки исключенных исключений?


Бонус вопрос: означает ли это, что пустая ссылка исключение внутри await блока не вызовет Visual Studio, чтобы остановить прямо там, но вместо того, чтобы остановится где-то совсем другое?

+2

Частный метод Task.Execute() содержит инструкцию catch all. HandleException и AddException после этого. Все частное и не виртуальное. –

+0

@HansPassant, если вы хотите опубликовать это как ответ (подразумевая, что это невозможно, в основном), я в конце концов приму его в отсутствие лучших ответов. –

ответ

3

Тип Task делает все исключения в AggregateException. Однако, если вы используете функциональность async/await, тогда, когда вы await a Task, внутреннее исключение разворачивается и повторно забрасывается, сохраняя исходную трассировку стека.

У VS11 будет более хорошая поддержка отладки async, но я не думаю, что можно пойти так далеко, как вы надеетесь. Task - это все о параллельном и асинхронном коде, поэтому я не думаю, что это когда-нибудь будет работать.

Рассмотрите, например, если у вас есть Task, работающий на потоке пула потоков, который вы собираетесь на await. Вы можете await его в блоке try, чтобы поймать исключение из Task ... или вы можете await его за пределами блока try, оставляя исключение Task незаменимым.

Точка с этим примером является то, что, когда исключение, отладчик не знает если исключение будет необработанными. С синхронным кодом, как только генерируется исключение, стек проверяется - и если он не обрабатывается, отладчик знает, что он необработан и может сразу предпринять специальные действия (до того, как стек будет даже размотан).

Итак, я не думаю, что можно делать то, что вы хотите. Вы можете приблизиться к IntelliTrace, хотя (только в VS Ultimate).

+2

Я понимаю, что он пойман, потому что не может знать, что-то захочет посмотреть на него _ вне_ задачи. Но я бы не сказал, что я хочу, просто невозможно; это просто не реализовано. Нет причин, по которым Task не может иметь «TaskCreationOption.LeaveExceptionsAlone». 'async' не будет указывать эту опцию для получения желаемых функций; Я бы указал, чтобы получить нужные функции. Увы, это не часть текущей реализации. –

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