try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
Yukarıdaki blokta, en sonunda blok ne zaman çağrılır? E atmadan önce veya nihayet çağrılır ve sonra yakalanır?
try {
// Do stuff
}
catch (Exception e) {
throw;
}
finally {
// Clean up
}
Yukarıdaki blokta, en sonunda blok ne zaman çağrılır? E atmadan önce veya nihayet çağrılır ve sonra yakalanır?
Yanıtlar:
E yeniden atıldıktan sonra çağrılır (yani, catch bloğu çalıştırıldıktan sonra)
Bu 7 yıl sonra düzenleme - Bir önemli not ise olmasıdır eçağrı yığını daha yukarı bir try / catch bloğu tarafından yakalanan veya küresel bir özel durum işleyici değil, o finallyblok olabilir hiç yürütmek asla.
finallyönceki atılmış istisna ise, gerçekleştirilen DEĞİLDİR catchasla yakalanmış bir dış içinde try- catchbloğun!
Neden denemiyorsun:
outer try
inner try
inner catch
inner finally
outer catch
outer finally
kodla (dikey boşluk için biçimlendirilmiş):
static void Main() {
try {
Console.WriteLine("outer try");
DoIt();
} catch {
Console.WriteLine("outer catch");
// swallow
} finally {
Console.WriteLine("outer finally");
}
}
static void DoIt() {
try {
Console.WriteLine("inner try");
int i = 0;
Console.WriteLine(12 / i); // oops
} catch (Exception e) {
Console.WriteLine("inner catch");
throw e; // or "throw", or "throw anything"
} finally {
Console.WriteLine("inner finally");
}
}
outer try inner try inner catch Unhandled Exception: System.DivideByZeroException...
Buradaki tüm cevapları okuduktan sonra, son cevap şuna bağlıdır :
Catch bloğu içinde yeniden bir istisna atarsanız ve bu istisna başka bir catch bloğunun içinde yakalanırsa, her şey belgelere göre yürütülür.
Bununla birlikte, re-trown istisnası işlenmezse, nihayet asla yürütülmez.
Bu kod örneğini VS2010 w / C # 4.0'da test ettim
static void Main()
{
Console.WriteLine("Example 1: re-throw inside of another try block:");
try
{
Console.WriteLine("--outer try");
try
{
Console.WriteLine("----inner try");
throw new Exception();
}
catch
{
Console.WriteLine("----inner catch");
throw;
}
finally
{
Console.WriteLine("----inner finally");
}
}
catch
{
Console.WriteLine("--outer catch");
// swallow
}
finally
{
Console.WriteLine("--outer finally");
}
Console.WriteLine("Huzzah!");
Console.WriteLine();
Console.WriteLine("Example 2: re-throw outside of another try block:");
try
{
Console.WriteLine("--try");
throw new Exception();
}
catch
{
Console.WriteLine("--catch");
throw;
}
finally
{
Console.WriteLine("--finally");
}
Console.ReadLine();
}
İşte çıktı:
Örnek 1: başka bir try bloğunun içine yeniden at:
--sonra dene
---- içsel deneme
---- içsel yakalama
---- içsel nihayet -
dıştan yakala
--sonunda
Huzzah!Örnek 2: Başka bir try'ın yeniden atmak dışında:
--try
--catchİşlenmeyen Özel Durum: System.Exception: 'System.Exception' türü özel durum oluştu.
ConsoleApplication1.Program.Main () konumunda C: \ local source \ ConsoleApplication1 \ Program.cs: satır 53
Örneğiniz bu kodla aynı şekilde davranacaktır:
try {
try {
// Do stuff
} catch(Exception e) {
throw e;
}
} finally {
// Clean up
}
Bir yan not olarak, gerçekten kastetiyorsanız throw e;(yani, yakaladığınız aynı istisnayı atın), yeni bir yığın oluşturmak yerine orijinal yığın izini koruyacağından, bunu yapmak çok daha iyidir throw;.
finallyBlok aslında sonra yürüteceği catchbenim pasajı göstermek için çalışıyor budur bloğun (catch bloğu özel durum rethrows bile).
trybloğun içinde cevabımın bir "dene-yakala" var. 3 parçalı yapının davranışını iki parçalı yapı kullanarak açıklamaya çalışıyorum. tryOrijinal soruda ikinci bir blok olduğuna dair herhangi bir işaret görmüyorum , bu yüzden bunu nereden anladığınızı anlamıyorum.
Bir catch işleyici bloğunun içinde işlenmemiş bir istisna varsa, final bloğu tam olarak sıfır kez çağrılır
static void Main(string[] args)
{
try
{
Console.WriteLine("in the try");
int d = 0;
int k = 0 / d;
}
catch (Exception e)
{
Console.WriteLine("in the catch");
throw;
}
finally
{
Console.WriteLine("In the finally");
}
}
Çıktı:
C: \ Users \ yönetici \ Belgeler \ TestExceptionNesting \ bin \ Release> TestExceptionNesting.exe
denemede
yakalamada
İşlenmeyen İstisna: System.DivideByZeroException: Sıfıra bölme denendi. C: \ users \ yönetici \ belgeler \ TestExceptionNesting \ TestExceptionNesting.cs: satır 22 içindeki TestExceptionNesting.Program.Main (String [] args)
C: \ Users \ yönetici \ Belgeler \ TestExceptionNesting \ bin \ release>
Bugün bir röportajda bu soruyu sordum ve görüşmeci geri dönüp durdu "sonunda aranmayacağından emin misin?" Bunun hileli bir soru mu yoksa mülakatı yapan kişinin aklında başka bir şey olup olmadığından ve hata ayıklamam için yanlış kod yazıp yazmadığından emin değildim, bu yüzden eve geldim ve denedim (inşa et ve çalıştır, hata ayıklayıcı etkileşimi yok), dinlenme.
Bir C # Konsol Uygulaması ile test edildiğinde, son kod, istisna atıldıktan sonra yürütüldü: "Uygulama Hatası İletişim Kutusu" mevcuttu ve "Programı kapat" seçeneğini seçtikten sonra, son blok o konsol penceresinde yürütüldü. Ama nihayet kod bloğunun içinde kırılma noktasını belirleyerek asla vuramam. Hata ayıklayıcı, throw deyiminde durmaya devam eder. İşte test kodum:
class Program
{
static void Main(string[] args)
{
string msg;
Console.WriteLine(string.Format("GetRandomNuber returned: {0}{1}", GetRandomNumber(out msg), msg) == "" ? "" : "An error has occurred: " + msg);
}
static int GetRandomNumber(out string errorMessage)
{
int result = 0;
try
{
errorMessage = "";
int test = 0;
result = 3/test;
return result;
}
catch (Exception ex)
{
errorMessage = ex.Message;
throw ex;
}
finally
{
Console.WriteLine("finally block!");
}
}
}
VS2010'da hata ayıklama - .NET Framework 4.0