Aslında, throw
ifadenin StackTrace bilgilerini korumayacağı bazı durumlar vardır . Örneğin, aşağıdaki kodda:
try
{
int i = 0;
int j = 12 / i; // Line 47
int k = j + 1;
}
catch
{
// do something
// ...
throw; // Line 54
}
StackTrace, satır 47'de yükseltilmesine rağmen, satır 54'ün istisnayı yükselttiğini gösterecektir.
Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.
at Program.WithThrowIncomplete() in Program.cs:line 54
at Program.Main(String[] args) in Program.cs:line 106
Yukarıda açıklananlara benzer durumlarda, orijinal StackTrace'i sunmak için iki seçenek vardır:
İstisna Çağırma.InternalPreserveStackTrace
Özel bir yöntem olduğundan, yansıma kullanılarak çağrılmalıdır:
private static void PreserveStackTrace(Exception exception)
{
MethodInfo preserveStackTrace = typeof(Exception).GetMethod("InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic);
preserveStackTrace.Invoke(exception, null);
}
StackTrace bilgilerini korumak için özel bir yönteme güvenmek dezavantajı var. .NET Framework'ün gelecekteki sürümlerinde değiştirilebilir. Yukarıdaki kod örneği ve aşağıda önerilen çözüm Fabrice MARGUERIE weblogundan alınmıştır .
Callception Exception.SetObjectData
Aşağıdaki teknik Anton Tykhyy tarafından C # 'a yanıt olarak önerildi , yığın izleme sorusunu kaybetmeden InnerException'ı nasıl yeniden arayabilirim .
static void PreserveStackTrace (Exception e)
{
var ctx = new StreamingContext (StreamingContextStates.CrossAppDomain) ;
var mgr = new ObjectManager (null, ctx) ;
var si = new SerializationInfo (e.GetType (), new FormatterConverter ()) ;
e.GetObjectData (si, ctx) ;
mgr.RegisterObject (e, 1, si) ; // prepare for SetObjectData
mgr.DoFixups () ; // ObjectManager calls SetObjectData
// voila, e is unmodified save for _remoteStackTraceString
}
Her ne kadar kamu yöntemlerine güvenme avantajına sahip olsa da, sadece aşağıdaki istisna kurucusuna da bağlıdır (üçüncü taraflarca geliştirilen bazı istisnalar geçerli değildir):
protected Exception(
SerializationInfo info,
StreamingContext context
)
Benim durumumda, ilk yaklaşımı seçmek zorunda kaldım, çünkü kullandığım üçüncü taraf bir kütüphane tarafından ortaya konan istisnalar bu yapıcıyı uygulamadı.