Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have Visual Studio stop on unhandled exceptions inside Task code?

Visual Studio has a certain feature that makes debugging unhandled exceptions a lot easier: it stops on the offending line of code and shows the exception.

It seems that the Task class is designed in such a way that this feature is always suppressed: it catches every exception, and then rethrows a different exception when the task is Waited or finalized.

I know I can have it stop on first-chance exceptions, but this doesn't always help: imagine that a number of handled exceptions of the same type occur prior to the unhandled one. In this case VS will stop on every non-problematic exception in addition to the one that actually causes the problem.

Another alternative is even less acceptable: just looking at the stack trace of the InnerException: this means that while I know which line caused the exception, I cannot access any of its local state, like I could if the program was actually stopped there.

Can I somehow get the best of both worlds, using the Task class but not having to live with the degraded exception debugging feature set?


Bonus question: does this mean that a null reference exception inside an await block will not cause Visual Studio to stop right there, but will instead stop somewhere else altogether?

like image 953
Roman Starkov Avatar asked Jan 26 '12 10:01

Roman Starkov


1 Answers

The Task type does wrap all exceptions into an AggregateException. However, if you're using the async/await functionality, then when you await a Task, the inner exception is unwrapped and re-thrown, preserving the original stack trace.

VS11 will have better async debugging support, but I don't think it's possible to go as far as what you're hoping. Task is all about concurrent and asynchronous code, and that's why I don't think this will ever work.

Consider, for example, if you have a Task running on a thread pool thread that you're going to await. You can await it in a try block to catch an exception from the Task... or you can await it outside of a try block, leaving the Task's exception to be unhandled.

The point with that example is that when the exception is thrown, the debugger doesn't know if the exception will be unhandled. With synchronous code, as soon as the exception is thrown, the stack is checked - and if it's unhandled, the debugger knows it is unhandled and can take special action right away (before the stack is even unwound).

So, I don't think it's possible to do what you want. You can get pretty close with IntelliTrace, though (only in VS Ultimate).

like image 136
Stephen Cleary Avatar answered Nov 02 '22 18:11

Stephen Cleary