using System;
namespace CallStackPreservation
{
class Program
{
private static void BadWork()
{
int i = 0;
int j = 12 / i; // Line 10
int k = j + 1;
}
private static void WithThrowEx()
{
try
{
BadWork();
}
catch (Exception ex)
{
// do something
// ...
throw ex; // Line 24
}
}
private static void WithThrow()
{
try
{
BadWork();
}
catch
{
// do something
// ...
throw; // Line 38
}
}
private static void WithThrowIncomplete()
{
try
{
int i = 0;
int j = 12 / i; // Line 47
int k = j + 1;
}
catch
{
// do something
// ...
throw; // Line 54
}
}
private static void WithThrowExAndStackTracePreservation()
{
try
{
BadWork();
}
catch (Exception ex)
{
// do something
// ...
PreserveStackTrace(ex);
throw ex; // Line 69
}
}
private static void WithThrowAndStackTracePreservation()
{
try
{
int i = 0;
int j = 12 / i; // Line 78
int k = j + 1;
}
catch (Exception ex)
{
// do something
// ...
PreserveStackTrace(ex);
throw; // Line 86
}
}
///
/// Sets a flag on an so that all the stack trace information is preserved when the exception is re-thrown.
///
///
/// This is useful because "throw" removes information, such as the original stack frame.
/// See http://dotnetjunkies.com/WebLog/chris.taylor/archive/2004/03/03/8353.aspx for more information on the technique used.
///
private static void PreserveStackTrace(Exception exception)
{
System.Reflection.MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
preserveStackTrace.Invoke(exception, null);
}
static void Main(string[] args)
{
//WithThrowEx(); // Line 88
//WithThrow(); // Line 89
//WithThrowIncomplete(); // Line 90
//WithThrowExAndStackTracePreservation(); // Line 91
WithThrowAndStackTracePreservation(); // Line 92
//try
//{
// F();
//}
//catch (Exception e)
//{
// Console.WriteLine("Exception {0} has occured!", e.GetType());
// throw; //Line 104
//}
}
public static void F()
{
throw new NotImplementedException("Too lazy to implement!");
}
}
}