Конференция ".Net" » Неожиданности при работе с исключениями [C#]
 
  • default © (22.08.06 13:22) [0]
    Вы непременно уверены, что блок finally выполняется всегда?
    а зря!

    using System;

    namespace ConsoleApplication4
    {

    class App
    {
     static void A() { A(); }

     //static void A() { throw new StackOverflowException(); }
     //static void A() { int i = 2/(i=0); }
     //static void A() { throw new DivideByZeroException(); }
     
       
     [STAThread]
     static void Main(string[] args)
     {
       
      try
      {  
       try
       {  
        A();
       }

       catch(Exception e)
       {
        Console.WriteLine("Exception1\n" + e.Message + "\n" + e.GetType().Name);
        A();  
       }

       finally
       {
        W("finally1");
       }

      }
      catch(Exception e)
      {
       Console.WriteLine("Exception2\n" + e.Message + "\n" + e.GetType().Name);
      }

      finally
      {
       W("finally2");
      }

         
     }
    }
    }


    внутренний блок finally остаётся в пролёте!
    поэкспериментируйте с закомментированными функциями A

    вопрос: что это? ошибка?
  • default © (22.08.06 13:26) [1]
    offtopic
    как сделать, чтобы исходное форматирование кода не изменялось при создании сообщения?
  • default © (22.08.06 13:28) [2]
    блин, вместо W в блоках finally поставьте Console.WriteLine
  • guav © (22.08.06 23:51) [3]
    Проверил этот код в студии 2005. первая версия A() приводит к невыполнению никакого дальнейшего кода. остальные версии - всё работает как надо.
    Видимо настоящий stack overflow это действительно серьёзно.
    В обычном win32 коде  после EStackOverflow память "портится", повторное переполнение может уже привести не к EStackOverflow  , а к другим исключениям.
  • default © (23.08.06 11:10) [4]
    guav ©   (22.08.06 23:51) [3]
    я запускал на Visual Studio .NET
    на ней при первой A() только внутренний finally не выводится
    при всех остальных A() всё хорошо

    кстати когда используется исключение по переполнению стека когда стек действительно переполнен(а не фиктивное throw new StackOverflowException();) один раз во внутреннем try(а в catch нет), то работает всё хорошо, но свойство e.StackTrac пусто...(не понятно почему ведь она должна выделятся под такие вещи из кучи, а не из стека)...странно в таких случаях должно всё нафиг вылетать...а так система полуживая, но продолжает работать...
  • Джо © (23.08.06 11:23) [5]
    > но свойство e.StackTrac пусто...(не понятно почему ведь
    > она должна выделятся под такие вещи из кучи, а не из стека)
    > .

    А что странного. "Вызов" свойства (то есть, вызов соответствующего метода-акксесора) сопровождается операцией со стеком. Может, отсюда и ноги.
  • default © (23.08.06 13:06) [6]
    Джо ©   (23.08.06 11:23) [5]
    тогда при вызове свойства должно возбуждаться снова StackOverflowException
    причина думаю в том, что StackTrace это цепочка методов от метода в котором возникло перехваченно исключение до метода в котором находится принимающий исключение catch
    исключение возникло при вызове из метода A некоего метода, а какого? снова A() и тд система, видимо, не предусматривает построение трассировки стека для такиц цепочек в которым метод в котором возникло исключение в некотором смысле неопределён

    интересно, отметить, что для фиктивных и настоящих переполнений стека свойство Message объекта-исключения имеет разные строки! говорится о переполнение стека, но по-разному
  • guav © (24.08.06 20:43) [7]
    Случайно нашел...

    http://msdn2.microsoft.com/en-us/library/633chdda.aspx

    Catching exception types derived from an interface is not supported under /clr. Also, the common language runtime does not permit you to catch stack overflow exceptions; a stack overflow exception will terminate the process.
  • guav © (24.08.06 21:12) [8]
    т.е. мной достигнутый результат, который и описан в мсдн. ссылка приведена для С++, однако и для http://msdn2.microsoft.com/en-us/library/w6sxk224.aspx здесь  то же самое без применения к С++ .
    Т.е. в [3] я достиг того, что описано в справке.

    Поведение [0], [4] когда повторное переполнение в catch приводит невыполнению первого finally объяснить пока трудно.

    Кстати, насчёт
    > win32 коде  после EStackOverflow память "портится", повторное
    > переполнение может уже привести не к EStackOverflow  , а
    > к другим исключениям.

    есть способ этого избежать http://msdn2.microsoft.com/en-us/library/89f73td2.aspx
  • default © (24.08.06 23:07) [9]
    guav ©   (24.08.06 21:12) [8]
    спасибо
    вот что нашёл
    "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. "
    у меня другая версия NET, младше
    и мсдн такой же старый на диске
    поэтому у меня работает, но как было продемонстрировано - в некоторых случаях криво
 
Конференция ".Net" » Неожиданности при работе с исключениями [C#]
Есть новые Нет новых   [120101   +61][b:0][p:0.001]