2012-09-11 20 views
10
yapar edilir

Olası Çoğalt: Genellikle .NET throw; yığın izlemesini sıfırlanmaz olduğu kabul edilmektedir
incorrect stacktrace by rethrowatış; yığın izleme sıfırlanmaz söylenir, ancak belli koşullar

ama throw ex; yapar.

void Main() 
{ 
    try 
    { 
     try 
     { 
      Wrapper(); // line 13 
     } 
     catch(Exception e) 
     { 
      Console.WriteLine(e.ToString()); 
      throw; // line 18 
     } 
    } 
    catch(Exception e) 
    { 
      Console.WriteLine(e.ToString()); 
    } 
} 

public void Wrapper() 
{ 
    Throw(); // line 28 
} 

public void Throw() 
{ 
    var x = (string)(object)1; // line 33 
} 

çıkışı:

System.Web.HttpUnhandledException: için türündeki nesne 'System.ınt32' yayın yapılamıyor

Ancak bu basit programda, farklı satır numaralarını almak 'System.String' yazın. ConsoleApplication2.Program.Main de (String [] args) C: \ uzun yol \ program.cs: hattı 13

System.InvalidCastException: tip 'System.ınt32' nesne türü döküm edilemiyor 'Sistemi .String'. ConsoleApplication2.Program.Main de (String [] args) C: \ uzun yol \ program.cs: hattı 18

Not: İlk yığın izleme hattı 13 içerir, ikinci ek hat 18 içerir ne satır 13 ne de satır 18, dökümün gerçekte gerçekleştiği satırlardır.

Soruma şimdi bakıyorum: throw; hangi koşullarda yığın izlemeyi değiştiriyor ve hangi durumda yığın izini değiştirmiyor?

Lütfen bunun zaten been observed olduğunu, ancak genel olarak yanıtlanmadığını unutmayın. Ben hata ayıklama modunda yukarıdaki kodu koştum
ve bu verir:


GÜNCELLEME

System.Web.HttpUnhandledException: 'yazın 'System.ınt32' türündeki nesne artığını açılamıyor System.String'. ConsoleApplication2'de ConsoleApplication2.Program.Throw (Program) 'da , ConsoleApplication2'de satır 33 : C: \ long-path \ Program.cs: satır 28 . C: \ long-path \ Program.cs: satır 13:

System.InvalidCastException: 'System.Int32' türünde nesne 'System.String' yazmak için kullanılamıyor. ConsoleApplication2'de ConsoleApplication2.Program.Throw (Program) 'da , ConsoleApplication2'de satır 33 : C: \ long-path \ Program.cs: satır 28 . Program.Main C (string [] args): \ uzun yol \ program.cs: satır 18

unutmayın:

+0

İstisnalar içinde ayrıntılandırılan satır numaralarının, sağladığınız kod snippet'i ile ilişkili olması durumunda yardımcı olur. –

+0

@PeterRitchie: Done. –

cevap

4

Darin zaten azaltılmış yığın izleme yöntemi inlining kaynaklanmaktadır işaret gibi. Bununla birlikte, yığın izinde eşit olmayan satır referansının noktası da vardır.

Bunun arkasındaki açıklamaları bilmiyorum, ancak bir istisnayı yeniden ele alırken tüm stacktrace bilgilerini tutmanın bir yolu var. Yeni bir istisna atmanız ve yakaladığınız kişiyi iç istisna olarak geçirmeniz gerekiyor. Bu yaklaşımla birleştirilen stacktrace, istisnanın orijini ve istisnanın yeniden işlendiği noktayı içerecektir.

Bu konuda konuştuk ve ertesi blog yazısında istisnalar rethrow farklı yollar üzerinde tam örnekler sundu:

.NET Exceptions – throw ex is evil but throw is not that innocent


Yorumunuz hızlı bir araştırma için beni motive ama en iyi bulabildiğim

Ayrıca t stacktrace satır numarasını değiştirir: catch and rethrow hakkında bir blog yazısı üzerine Jonathan de Halleux tarafından bu yorumdu O, 'un (bu yöntemde atım atma yeri haline geldiğinden) tekrarladığı yöntemi kullanır.

Bu da özenli olabilir, ama muhtemelen daha sonra hat bilgilerini almak için kullanılacak atmak sitesi her yöntem izlenir ve rethrow bunun geçersiz neden olur gerçeğine işaret

.

throw e yerine throw kullanıldığında stacktrace korunmuş olsa da, yeni bir özel durum atlayıp atmadığınız sürece orijinal atma yeri kaybolur.

Denenmesi gereken diğer şeyler; SO doğrudan mesajlara izin vermediğinden ve yukarıdaki yorum Peli tarafından yapıldığından, dikkatini çekmek ve bu yorumu takip etmesini sağlamak için bu soruyu pex ile etiketlemeye çalışabilirsiniz. :)

+1

Teşekkürler. Bunu tamamlamanın yığın yığın izini koruyacağını biliyorum. Bu soruyu, insanların sadece "atmak", "yığın izini koruduğu gibi" kullanacakları gelecekteki gönderiler için bir referans almasını istedim. –

+0

Soruyu, daha önce gördüğünüz, daha önce gördüğünüz, daha önce gördüğünüz, ancak referans olarak kullanabileceğiniz, faydalı olabilir. Bununla birlikte, hala konuyu tamamen açıklamıyor. –

5

bu olay nedeni yüzünden son satırı sayısı hala değiştirir olduğunu Serbest bırakma modunda çalışırken satır içi yöntem.Eğer Wrapper ve Throw yöntemler yayın modunda satır içine yerleştirilmiş etmek istemiyorsanız size [MethodImpl] özniteliği ile süslemek olabilir:

[MethodImpl(MethodImplOptions.NoInlining)] 
public void Wrapper() 
{ 
    Throw(); 
} 

[MethodImpl(MethodImplOptions.NoInlining)] 
public void Throw() 
{ 
    var x = (string)(object)1; 
} 
+1

Tamam, bu ilk yakalamadaki satır numarasının neden satırın satır numarası olmadığını açıklıyor. Hala neden atıldığını açıklamıyor, 'yığın izinde satır sayısını değiştiriyor. –

+0

Bu satırlar boyunca bir şey söylemek üzereydim, bu yüzden sadece eklemek için: Kodun hata ayıklama modunda çalıştırılması, her ikisi de 'Atma' yönteminden kaynaklanan tam arama yığınlarını verir. –

+0

@DanielHilgarth Gördüğünüz satır numarası, istisnanın yeniden atıldığı satırdır. Bir sürüm oluşturmada, geri kalanı çizikli olduğu için aldığınız tek şey budur. Özel durumun kaynağını istiyorsanız, tam yığına ihtiyacınız vardır. –

İlgili konular