C# - How does one handle/catch StackOverFlowExceptions?
I don't 开发者_Go百科need a lesson in switching from recursive to non-recursive means, I just want to know why we can't deal with this type of exception. Regardless, I'm using recursive functions on very large lists.
I have written code to attempt to catch StackOverFlowExceptions:
try { recursiveFxn(100000); }
catch(Exception){}
private void recursiveFxn(int countdown)
{
if (countdown > 0)
recursiveFxn(countdown - 1);
else
throw new Exception("lol. Forced exception.");
}
But still I get program crashes (in both NUnit and a webpage I'm running). Why isn't the exception caught?
Since .NET Framework 2.0, StackOverflowException
cannot be caught. This is because it is considered a bad practice. Quoting the MSDN documentation:
Starting with the .NET Framework version 2.0, a
StackOverflowException
object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop.
Now, the only way to catch a StackOverflowException
is when it was thrown by user code, as explained in a blog by Jared Parsons. Other than that, by hosting the CLR, you can handle (but not catch) a StackOverflowException
and devise a way to let the execution of your program continue.
Note that because the stack is unwound when an exception occurs, in pre-2.0 versions of .Net the stack would actually be much shorter when the StackOverflowException
is handled, making it possible to do so without generating another StackOverflowException
.
You can't catch a stack overflow exception because when it happens it kills the thread dead. Try... catch... is performed by the same thread so that won't work. There may be some lower level APIs that you could P/Invoke and have another thread catch it. There may also be some lower level APIs to change the maximum stack size, but I don't see anything in the .NET Framework to help with that so again you would need to P/Invoke something.
精彩评论