Почему исключение .NET не перехватывается блоком try / catch?

StackOverflow https://stackoverflow.com/questions/36014

  •  09-06-2019
  •  | 
  •  

Вопрос

Я работаю над проектом, использующим ANTLR библиотека синтаксического анализа для C #.Я создал грамматику для синтаксического анализа некоторого текста, и она работает хорошо.Однако, когда анализатор обнаруживает незаконный или неожиданный токен, он выдает одно из многих исключений.Проблема в том, что в некоторых случаях (не во всех) мой блок try / catch не перехватит его и вместо этого остановит выполнение как необработанное исключение.

Проблема для меня в том, что я не могу воспроизвести эту проблему нигде больше, кроме как в моем полном коде.Стек вызовов показывает, что исключение определенно возникает в моем блоке try / catch (Исключение).Единственное, о чем я могу думать, это о том, что есть несколько вызовов сборки ANTLR, которые происходят между моим кодом и кодом, вызывающим исключение, и в этой библиотеке не включена отладка, поэтому я не могу пройти через это.Интересно, запрещают ли не отлаживаемые сборки генерирование исключений?Стек вызовов выглядит следующим образом;вызовы внешней сборки выполняются в Antlr.Среда выполнения:

    Expl.Itinerary.dll!TimeDefLexer.mTokens() Line 1213 C#
    Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xfc bytes 
    Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x22c bytes   
    Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 1) + 0x68 bytes
    Expl.Itinerary.dll!TimeDefParser.prog() Line 109 + 0x17 bytes   C#
    Expl.Itinerary.dll!Expl.Itinerary.TDLParser.Parse(string Text = "", Expl.Itinerary.IItinerary Itinerary = {Expl.Itinerary.MemoryItinerary}) Line 17 + 0xa bytes C#

Фрагмент кода из самого нижнего вызова в Parse() выглядит следующим образом:

     try {
        // Execution stopped at parser.prog()
        TimeDefParser.prog_return prog_ret = parser.prog();
        return prog_ret == null ? null : prog_ret.value;
     }
     catch (Exception ex) {
        throw new ParserException(ex.Message, ex);
     }

На мой взгляд, предложение catch (Exception) должно было фиксировать любое исключение вообще.Есть ли какая-то причина, почему этого не произошло бы?

Обновить: Я проследил за внешним узлом с отражателем и не обнаружил никаких признаков нарезания резьбы вообще.Сборка, похоже, просто является служебным классом среды выполнения для сгенерированного ANTLR кода.Генерируется исключение из TimeDefLexer .Метод mTokens() и его тип - NoViableAltException, который является производным от RecognitionException -> Исключение.Это исключение выдается, когда лексер не может понять следующий токен в потоке;другими словами, неверный ввод.Это исключение должно было произойти, однако оно должно было быть перехвачено моим блоком try / catch.

Кроме того, повторное удаление ParserException действительно не имеет отношения к этой ситуации.Это уровень абстракции, который принимает любое исключение во время синтаксического анализа и преобразует в мое собственное ParserException.Проблема с обработкой исключений, с которой я сталкиваюсь, заключается в том, что я никогда не достигаю этой строки кода.Фактически, я закомментировал часть "создать новое исключение ParserException" и все равно получил тот же результат.

Еще одна вещь, я изменил исходный блок try / catch, о котором идет речь, чтобы вместо этого перехватывать исключение NoViableAltException, устраняя любую путаницу с наследованием.Я все равно получил тот же результат.

Кто-то однажды предположил, что иногда VS чрезмерно активен при перехвате обработанных исключений в режиме отладки, но эта проблема также возникает в режиме выпуска.

Блин, я все еще в тупике!Я не упоминал об этом раньше, но я использую версию 2008, и весь мой код равен 3.5.Внешняя сборка - 2.0.Кроме того, некоторые из моих подклассов кода относятся к классу в сборке 2.0.Может ли несоответствие версий вызвать эту проблему?

Обновление 2: Я смог устранить конфликт .NET version, перенеся соответствующие части моего кода .NET 3.5 в проект .NET 2.0 и повторив тот же сценарий.Мне удалось воспроизвести то же самое необработанное исключение при постоянном запуске в .NET 2.0.

Я узнал, что ANTLR недавно выпустила версию 3.1.Итак, я обновился с версии 3.0.1 и повторил попытку.Оказывается, сгенерированный код немного переработан, но то же самое необработанное исключение возникает в моих тестовых примерах.

Обновление 3: Я воспроизвел этот сценарий в упрощенный проект ПО СРАВНЕНИЮ с 2008 годом.Не стесняйтесь скачать и ознакомиться с проектом самостоятельно.Я применил все замечательные предложения, но пока не смог преодолеть это препятствие.

Если вы можете найти обходной путь, пожалуйста, поделитесь своими выводами.Еще раз спасибо!


Спасибо, но VS 2008 автоматически прерывается при необработанных исключениях.Кроме того, у меня нет диалогового окна Debug-> Exceptions.Вызываемое исключение NoViableAltException полностью предназначено и предназначено для перехвата пользовательским кодом.Поскольку он не перехвачен должным образом, выполнение программы неожиданно прекращается как необработанное исключение.

Генерируемое исключение является производным от Exception, и с ANTLR многопоточность не выполняется.

Это было полезно?

Решение

Мне кажется, я понимаю проблему.Исключение перехватывается, проблема заключается в путанице в поведении отладчика и различиях в настройках отладчика у каждого пользователя, пытающегося его воспроизвести.

В 3-м случае из вашего репро, я полагаю, вы получаете следующее сообщение:"NoViableAltException не было обработано пользовательским кодом" и стек вызовов, который выглядит следующим образом:

         [External Code]    
    >   TestAntlr-3.1.exe!TimeDefLexer.mTokens() Line 852 + 0xe bytes   C#
        [External Code] 
        TestAntlr-3.1.exe!TimeDefParser.prog() Line 141 + 0x14 bytes    C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") Line 49 + 0x9 bytes C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) Line 30 + 0xb bytes C#
        [External Code] 

Если вы щелкните правой кнопкой мыши в окне callstack и запустите включить отображение внешнего кода, вы увидите следующее:

        Antlr3.Runtime.dll!Antlr.Runtime.DFA.NoViableAlt(int s = 0x00000000, Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x80 bytes   
        Antlr3.Runtime.dll!Antlr.Runtime.DFA.Predict(Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x21e bytes  
    >   TestAntlr-3.1.exe!TimeDefLexer.mTokens() Line 852 + 0xe bytes   C#
        Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xc4 bytes 
        Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x147 bytes   
        Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 0x00000001) + 0x2d bytes  
        TestAntlr-3.1.exe!TimeDefParser.prog() Line 141 + 0x14 bytes    C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") Line 49 + 0x9 bytes C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) Line 30 + 0xb bytes C#
        [Native to Managed Transition]  
        [Managed to Native Transition]  
        mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39 bytes    
        Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes  
        mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes   
        mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes    
        mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes

Сообщение отладчика сообщает вам, что исключение, возникающее вне вашего кода (из NoViableAlt), проходит через ваш собственный код в TestAntlr-3.1.exe!TimeDefLexer.mTokens() не обрабатывается.

Формулировка сбивает с толку, но это не означает, что исключение не перехвачено.Отладчик сообщает вам, что ваш собственный код mTokens()"должен быть устойчив к этому исключению, генерируемому через него.

С чем стоит поиграть, чтобы посмотреть, как это выглядит для тех, кто не сообщал о проблеме:

  • Перейдите в Сервис / Параметры / Отладка и отключите опцию "Включить только мой код (только управляемый)".или вариант.
  • Перейдите в раздел Debugger/Exceptions и отключите "User-unhandled" для общеязыковых исключений среды выполнения.

Другие советы

Независимо от того, была ли сборка скомпилирована как сборка выпуска, исключение должно определенно «всплывать» до вызывающей стороны, нет никаких причин, по которым сборка, не скомпилированная в режиме отладки, должна иметь какое-либо влияние на это.

Я согласен с предположением Дэниела о том, что, возможно, исключение происходит в отдельном потоке - попробуйте перехватить событие исключения потока в Application.ThreadException. Это должно быть поднято, когда происходит любое необработанное исключение потока. Вы можете адаптировать свой код таким образом: -

using System.Threading;

...

void Application_ThreadException(object sender, ThreadExceptionEventArgs e) {
  throw new ParserException(e.Exception.Message, e.Exception);
}    

 ...

 var exceptionHandler = 
    new ThreadExceptionEventHandler(Application_ThreadException);
 Application.ThreadException += exceptionHandler;
 try {
    // Execution stopped at parser.prog()
    TimeDefParser.prog_return prog_ret = parser.prog();
    return prog_ret == null ? null : prog_ret.value;
 }
 catch (Exception ex) {
    throw new ParserException(ex.Message, ex);
 }
 finally {
    Application.ThreadException -= exceptionHandler;
 }

Используете ли вы .Net 1.0 или 1.1? Если это так, то catch (Exception ex) не будет ловить исключения из неуправляемого кода. Вам нужно будет использовать catch {}. Смотрите эту статью для получения дополнительной информации:

http://www.netfxharmonics.com/2005 / 10 / нетто-20-trycatch-и-trycatchexception /

Я могу рассказать вам, что здесь происходит ...

Visual Studio ломается, потому что считает исключение необработанным. Что значит необработанный? Что ж, в Visual Studio есть настройка в меню Инструменты ... Параметры ... Отладка ... Общие ... " Включить только мой код (только управляемый) " ;. Если это проверено, и если исключение распространяется из вашего кода и выходит во фрейм стека, связанный с вызовом метода, который существует в сборке, которая «НЕ ВАШ КОД» (например, Antlr), который считается «необработанным». По этой причине я отключаю эту функцию. Но, если вы спросите меня, это неубедительно ... допустим, вы делаете это:

ExternalClassNotMyCode c = new ExternalClassNotMyCode();
try {
    c.doSomething( () => { throw new Exception(); } );
}
catch ( Exception ex ) {}

doSomething вызывает вашу анонимную функцию, и эта функция вызывает исключение ...

Обратите внимание, что это "необработанное исключение" в соответствии с Visual Studio, если " Включить только мой код " включен Кроме того, обратите внимание, что он останавливается, как если бы он был точкой останова в режиме отладки, но в среде без отладки или в рабочей среде код является абсолютно корректным и работает, как и ожидалось. Кроме того, если вы просто "продолжите" в отладчике приложение идет своим чередом (не останавливает поток). Это считается "необработанным" потому что исключение распространяется через стековый фрейм, который НЕ находится в вашем коде (т.е. во внешней библиотеке). Если вы спросите меня, это паршиво. Пожалуйста, измените это поведение по умолчанию Microsoft. Это вполне допустимый случай использования исключений для управления логикой программы. Иногда вы не можете изменить стороннюю библиотеку на другое поведение, и это очень полезный способ для решения многих задач.

Возьмем, к примеру, MyBatis, вы можете использовать эту технику, чтобы остановить обработку записей, которые собираются с помощью вызова SqlMapper.QueryWithRowDelegate.

Возможно ли, что исключение выдается в другом потоке? Очевидно, ваш вызывающий код однопоточный, но, возможно, библиотека, которую вы используете, выполняет некоторые многопоточные операции под прикрытием.

Я с @Shaun Austin - попробуйте завершить попытку с полным именем

catch (System.Exception)

и посмотрите, поможет ли это. Документ ANTLR сообщает, какие исключения следует выдавать?

  

Для меня предложение catch (Exception) должно было охватить любое исключение. Есть ли причина, почему это не так?

Единственная возможность, о которой я могу подумать, - это то, что кто-то другой ловит это перед вами и обрабатывает таким образом, который кажется неперехваченным исключением (например, выход из процесса).

  

мой блок try / catch не перехватит его и остановит выполнение как необработанное исключение.

Вам нужно найти причину процесса выхода. Это может быть что-то иное, чем необработанное исключение. Вы можете попытаться использовать собственный отладчик с точкой останова, установленной в " {,, kernel32.dll} ExitProcess " ;. Затем используйте SOS , чтобы определить, что такое управляемый код вызов процесса выхода.

Лично меня вообще не убеждает теория потоков.

Однажды, когда я видел это раньше, я работал с библиотекой, которая также определила Exception, и употребления, которые я имел в виду, что фактический Catch имел в виду другое «Exception» quot; type (если он был полностью определен, то это Company.Lib.Exception, но не из-за использования), поэтому, когда дело доходит до перехвата нормального исключения, которое выдается (какое-то исключение аргумента, если я правильно помню), оно просто не поймать его, потому что тип не соответствует.

Итак, вкратце, есть ли другой тип исключения в другом пространстве имен, который используется в этом классе?

РЕДАКТИРОВАТЬ: быстрый способ проверить это - убедиться, что в предложении catch вы полностью квалифицировали тип Exception как " System.Exception " и крутись!

РЕДАКТИРОВАТЬ2: ОК, я попробовал код и пока признаю поражение. Мне придется еще раз взглянуть на это утром, если никто не придумал решения.

Хм, я не понимаю проблемы. Я скачал и попробовал ваш пример файла решения.

Исключение выдается в TimeDefLexer.cs, строка 852, которая впоследствии обрабатывается блоком catch в Program.cs, который просто говорит Обработанное исключение .

Если я раскомментирую блок catch над ним, он вместо этого войдет в этот блок.

В чем здесь проблема?

Как сказал Кибби, Visual Studio остановится на исключениях, но если вы попросите его продолжить, исключение будет перехвачено вашим кодом.

Я скачал пример проекта VS2008, и здесь я тоже немного озадачен. Однако я смог преодолеть исключения, хотя, вероятно, не так, чтобы это сработало. Но вот что я нашел:

Эта запись в списке рассылки имела обсуждение того, что похоже на ту же проблему, с которой вы столкнулись.

Оттуда я добавил пару фиктивных классов в основной файл program.cs:

class MyNoViableAltException : Exception
{
    public MyNoViableAltException()
    {
    }
    public MyNoViableAltException(string grammarDecisionDescription, int decisionNumber, int stateNumber, Antlr.Runtime.IIntStream input)
    {
    }
}
class MyEarlyExitException : Exception
{
    public MyEarlyExitException()
    {
    }

    public MyEarlyExitException(int decisionNumber, Antlr.Runtime.IIntStream input)
    {
    }
}

, а затем добавил используемые строки в TimeDefParser.cs и TimeDefLexer.cs:

using NoViableAltException = MyNoViableAltException;
using EarlyExitException = NoViableAltException; 

При этом исключения будут пузыриться в ложные классы исключений и могут обрабатываться там, но в методе mTokens в TimeDefLexer.cs по-прежнему возникает исключение. Обтекание, что в try catch в этом классе поймано исключение:

            try
            {
                alt4 = dfa4.Predict(input);
            }
            catch
            {
            }

Я действительно не понимаю, почему оборачивать его во внутренний метод, а не туда, откуда он вызывается, обрабатывать ошибку, если многопоточность не в игре, но в любом случае, надеюсь, это укажет кого-то умнее меня в правильном направлении. .

Я скачал твой код и все работает как положено.

Отладчик Visual Studio правильно перехватывает все исключения. Поймать блоки работают как положено.

Я использую Windows 2003 server SP2, VS2008 Team Suite (9.0.30729.1 SP)

Я попытался скомпилировать ваш проект для .NET 2.0, 3.0 & amp; 3.5

@ Steve Steiner, упомянутые вами опции отладчика не имеют ничего общего с этим поведением.

Я попытался поиграть с этими опциями без видимых эффектов - блоки catch смогли перехватить все исключения.

Стив Штейнер прав, что исключение происходит из библиотеки antlr, проходит через метод mTokens () и перехватывается в библиотеке antlr. Проблема в том, что этот метод автоматически генерируется antlr. Поэтому любые изменения для обработки исключения в mTokens () будут перезаписаны при создании классов вашего синтаксического анализатора / лексера.

По умолчанию antlr регистрирует ошибки и пытается восстановить синтаксический анализ. Вы можете переопределить это так, чтобы parser.prog () генерировал исключение при возникновении ошибки. Из вашего примера кода я думаю, что это поведение, которое вы ожидали.

Добавьте этот код в файл грамматики (.g). Вам также необходимо отключить " Включить только мой код " в меню отладки.

@members {

    public override Object RecoverFromMismatchedSet(IIntStream input,RecognitionException e,    BitSet follow)  
    {
        throw e;
    }
}

@rulecatch {
    catch (RecognitionException e) 
    {
        throw e;
    }
}

Это моя попытка версии C # примера, приведенного в разделе «Выход из распознавателя при первой ошибке». глава «Полное руководство по ANTLR» книга.

Надеюсь, это то, что вы искали.

Вы можете настроить VS.Net на разрыв, как только произойдет любое исключение. Просто запустите ваш проект в режиме отладки, и он остановится, как только будет сгенерировано исключение. Тогда вы должны лучше понять, почему его не поймали.

Кроме того, вы можете вставить некоторый код в перехватить все необработанные исключения . Прочитайте ссылку для получения дополнительной информации, но основы этих двух строк.

Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);

 // Catch all unhandled exceptions in all threads.
 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);

Да, и в отношении того, что сказал Кибби; если вы выберете Debug | Exceptions в VS и просто нажмете все поля в столбце «выбросить», он должен выбрать «em> everything AFAIK» как «исключение первого шанса», то есть VS будет указывать, когда исключение составляет < em> about обрабатывается всем остальным и разбивается на соответствующий код. Это должно помочь с отладкой.

Лучший вариант звучит как установка Visual Studio для разрыва всех необработанных исключений (диалоговое окно «Отладка -> исключения», установите флажок «Общие исключения для среды выполнения» и, возможно, другие). Затем запустите вашу программу в режиме отладки. Когда код синтаксического анализатора ANTLR генерирует исключение, он должен быть перехвачен Visual Studio и позволит вам увидеть, где это происходит, тип исключения и т. Д.

Исходя из описания, блок catch выглядит правильным, поэтому может происходить одно из следующих действий:

<Ол>
  • синтаксический анализатор фактически не выдает исключение
  • парсер в конечном итоге выдает что-то, что не является производным от System.Exception
  • в другом потоке возникает исключение, которое не обрабатывается
  • Похоже, вы потенциально исключили проблему № 3.

      

    Я проследил через внешнюю сборку с помощью Reflector и не нашел никаких доказательств наличия потоков.

    Вы не можете найти ни одного потока, это не значит, что никакого потока нет

    .NET имеет «пул потоков», который представляет собой набор «запасных» потоков, которые в основном бездействуют. Определенные методы заставляют вещи выполняться в одном из потоков пула потоков, чтобы они не блокировали ваше основное приложение.

    Яркими примерами являются такие вещи, как ThreadPool.QueueUserWorkItem , но есть множество других вещей, которые также могут запускать вещи в пуле потоков, которые не выглядят такими очевидными, как, например, Delegate.BeginInvoke

    На самом деле, вам нужно делать то, что предлагает Кибби .

    Вы пытались напечатать (Console.WriteLine ()) исключение внутри предложения catch и не использовали Visual Studio и не запускали приложение на консоли?

    Я считаю, что Стив Штейнер прав. Исследуя предложения Стива, я натолкнулся на в этой теме рассказывает о " Включить только мой код " опция в Сервис | Параметры | Отладчик | Общие. Предполагается, что отладчик будет зависать при определенных условиях, когда не пользовательский код генерирует или обрабатывает исключение. Я не совсем уверен, почему это вообще имеет значение, или почему отладчик специально говорит, что исключение было необработанным, когда оно действительно было.

    Мне удалось устранить ложные перерывы, отключив параметр " Включить только мой код " вариант. Это также изменяет диалоговое окно «Отладка | Исключения», удаляя «Обработано пользователем». колонка как то больше не применяется. Или вы можете просто снять флажок " Обработано пользователем " поле для CLR и получить тот же результат.

    Большое спасибо всем за помощь!

      

    " Кроме того, вы можете поместить некоторый код в   поймать все необработанные исключения. Читать   ссылка для получения дополнительной информации, но основы   эти две строки. "

    Это неверно. Раньше он перехватывал все необработанные исключения в .NET 1.0 / 1.1, но это была ошибка, и не предполагалось, и это было исправлено в .NET 2.0.

    AppDomain.CurrentDomain.UnhandledException 
    

    Предназначен только для использования в качестве последнего окна регистрации событий, поэтому вы можете записать исключение до выхода из программы. Он не будет ловить исключение начиная с версии 2.0 (хотя, по крайней мере, в .NET 2.0 есть значение конфигурации, которое вы можете изменить, чтобы оно работало как 1.1, но это не рекомендуется использовать).

    Стоит отметить, что есть несколько исключений, которые вы не можете перехватить, таких как StackOverflowException и OutOfMemoryException. В противном случае, как полагают другие, это может быть где-то исключение в фоновом потоке. Также я почти уверен, что вы не можете перехватить некоторые / все неуправляемые / нативные исключения.

    Я не понимаю ... ваш блок catch просто генерирует новое исключение (с тем же сообщением). Это означает, что ваше утверждение:

      

    Проблема в том, что в некоторых случаях (не во всех) мой блок try / catch не может его перехватить и вместо этого останавливает выполнение как необработанное исключение.

    - это именно то, что ожидается .

    Я согласен с Даниэлем Аугером и kronoz что это пахнет как исключение, которое имеет отношение к потокам. Кроме того, вот мои другие вопросы:

    <Ол>
  • Что говорит полное сообщение об ошибке? Что это за исключение?
  • Исходя из предоставленной здесь трассировки стека, не является ли исключение, созданное вами, кодом в TimeDefLexer.mTokens ()?
  • Я не уверен, что мне неясно, но если это так, я вижу, как отладчик прекращает выполнение с " Unhandled Exception " типа NoViableAltException. Изначально я ничего не знал об этом пункте меню «Отладка -> Исключения», поскольку MS ожидает, что во время установки VS вы передадите профиль, если вы не знаете, чем они отличаются. По-видимому, Я не был в профиле C # dev и пропускал эту опцию . После окончательной отладки всех сгенерированных исключений CLR я, к сожалению, не смог обнаружить какое-либо новое поведение, приводящее к причине этой необработанной проблемы исключения. Все сгенерированные исключения ожидались и предположительно обрабатывались в блоке try / catch.

    Я просмотрел внешнюю сборку, и нет признаков многопоточности. Под этим я подразумеваю, что ссылки на System.Threading не существует, и делегаты не использовались вообще. Я знаком с тем, что представляет собой создание потока. Я проверяю это, наблюдая за набором инструментов Threads во время необработанного исключения, чтобы увидеть, что существует только один работающий поток.

    У меня есть открытая проблема с людьми из ANTLR, поэтому, возможно, они уже могли решить эту проблему раньше. Мне удалось воспроизвести его в простом проекте консольного приложения с использованием .NET 2.0 и 3.5 под VS 2008 и VS 2005.

    Это просто болевая точка, потому что он заставляет мой код работать только с известным допустимым вводом синтаксического анализатора. Использование метода IsValid () было бы рискованно, если бы оно вызывало необработанное исключение на основе пользовательского ввода. Я буду держать этот вопрос в актуальном состоянии, когда станет известно больше об этой проблеме.

    @споулсон,

    Если вы можете воспроизвести это, не могли бы вы разместить это где-нибудь?Один из способов, который вы могли бы попробовать, - это использовать WinDbg с расширениями SOS для запуска приложения и перехвата необработанного исключения.Он прервется при первом случайном исключении (до того, как среда выполнения попытается найти обработчик), и в этот момент вы сможете увидеть, откуда оно исходит и из какого потока.

    Если вы раньше не использовали WinDbg, это может быть немного затруднительно, но вот хороший учебник:

    http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx

    Как только вы запустите WinDbg, вы можете переключить удаление необработанных исключений, перейдя в раздел Отладка-> Фильтры событий.

    Ничего себе, так что из отчетов до сих пор 2 работали правильно, и 1 столкнулся с проблемой, о которой я сообщил. Какие версии Windows, Visual Studio используются и .NET Framework с номерами сборки?

    Я использую XP SP2, VS 2008 Team Suite (9.0.30729.1 SP), C # 2008 (91899-270-92311015-60837) и .NET 3.5 SP1.

    Если вы используете com-объекты своего проекта и пытаетесь ловить блоки, чтобы не перехватывать исключения, вам потребуется отключить инструменты / отладку / разрыв, когда исключения пересекают AppDomain или управляемые / собственные границы (только управляемые).

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top