Почему исключение.NET не поймано блоком попытки/выгоды?

Нет, нет. Точка on() - это другие ее перегрузки и возможность обрабатывать события, которые не имеют методов быстрого доступа.

45
задан 9 revs, 4 users 88% 24 March 2012 в 08:46
поделиться

23 ответа

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

В 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] 

, Если Вы щелкаете правой кнопкой в окне стека вызовов и выполняете поворот выставленный внешний код, Вы видите это:

        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 ()", должно быть устойчивым против этого исключения, бросаемого через него.

Вещи играть с видеть, как это ищет тех, кто не сделал репродукции проблема:

  • Переходят к Инструментам/Опциям/Отладке и выключают, "Включают Просто Мой код (Управляемый только)". или опция.
  • Переходят к Отладчику/Исключениям и выключают "необработанный Пользователем" для Исключений Общеязыковой среды выполнения.
30
ответ дан Jeff Atwood 26 November 2019 в 21:20
поделиться

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

я выполняю XP SP2, комплект VS 2008 Команды (9.0.30729.1 SP), C# 2008 (91899-270-92311015-60837) и.NET 3,5 SP1.

0
ответ дан spoulson 26 November 2019 в 21:20
поделиться

@spoulson,

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

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

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

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

0
ответ дан Cory Foy 26 November 2019 в 21:20
поделиться

Я не уверен, неясен ли я, но если так, я вижу, что отладчик останавливает выполнение с "Необработанным исключением" типа NoViableAltException. Первоначально, я ничего не знал об этом пункте меню Debug-> Exceptions, потому что MS ожидает, что Вы, во время установки VS, согласитесь на профиль, когда Вы будете понятия не иметь, как они отличаются. По-видимому, я не был на профиле C# dev и пропускал эту опцию . После окончательной отладки всех выданных исключений CLR я был, к сожалению, неспособен обнаружить любое новое продвижение поведения к причине этой проблемы необработанного исключения. Все брошенные исключения ожидались и предположительно обрабатывались в блоке попытки/выгоды.

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

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

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

0
ответ дан spoulson 26 November 2019 в 21:20
поделиться

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

  1. , Что говорит полное сообщение об ошибке? Какое исключение - он?
  2. На основе отслеживания стека Вы обеспечили здесь, разве исключение не выдается Вами код в TimeDefLexer.mTokens ()?
0
ответ дан Community 26 November 2019 в 21:20
поделиться

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

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

точно, что , ожидал происходить.

0
ответ дан Mark Brackett 26 November 2019 в 21:20
поделиться

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

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

AppDomain.CurrentDomain.UnhandledException 

только предназначается, чтобы использоваться в качестве последнего седана входа шанса, таким образом, можно зарегистрировать исключение перед выходами программы. Это выгода привычки исключение с 2,0 вперед (хотя в.NET 2.0, по крайней мере, существует значение конфигурации, можно изменить, чтобы заставить его действовать как 1,1, но это не методические рекомендации для использования этого.).

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

0
ответ дан Quibblesome 26 November 2019 в 21:20
поделиться

Я полагаю, что Steve Steiner корректен. При исследовании предложений Steve я столкнулся этот поток разговор об опции "Enable Just My Code" в Tools|Options|Debugger|General. Предложено, чтобы отладчик прервал определенные условия, когда код лица, не использующего своего права или бросит или обрабатывает исключение. Я не абсолютно уверен, почему это даже имеет значение, или почему отладчик конкретно говорит, что исключение было не обработано, когда это действительно было.

я смог устранить ложные повреждения путем отключения опции "Enable Just My Code". Это также изменяет диалоговое окно Debug|Exceptions путем удаления столбца "User-handled", поскольку это больше не применяется. Или, можно просто снять флажок "User-handled" для CLR и получить тот же результат.

Большой успех благодарит за справку всех!

1
ответ дан spoulson 26 November 2019 в 21:20
поделиться

Вы попытались распечатать (Консоль. WriteLine ()) исключение в пункте выгоды, и не Visual Studio использования и запущенный Ваше приложение на консоли?

1
ответ дан Eduardo Diaz 26 November 2019 в 21:20
поделиться

я проследил посредством внешнего блока с Отражателем и не нашел доказательства поточной обработки вообще.

Вы не можете найти, что любая поточная обработка не означает, что нет никакой поточной обработки

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

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

Действительно, Вам нужно к , делают то, что kibbee предлагает .

1
ответ дан Community 26 November 2019 в 21:20
поделиться

О, и в отношении того, что заявил Kibbee; если Вы выбираете Debug|Exceptions в VS и просто нажимаете все поля в 'брошенном' столбце, это должно выбрать все AFAIK как 'первое случайное исключение', т.е. VS укажет, когда исключение будет [приблизительно 111], чтобы быть обработанным всем остальным и повреждением на соответствующих нормах. Это должно помочь с отладкой.

1
ответ дан ljs 26 November 2019 в 21:20
поделиться

Наилучший вариант походит на установку Visual Studio, чтобы повредиться на всех необработанных исключениях (Отладка-> диалоговое окно Исключений, установить флажок для "Исключений Общеязыковой среды выполнения" и возможно других также). Тогда запустите свою программу в режиме отладки. Когда код синтаксического анализатора ANTLR выдает исключение, он должен быть пойман Visual Studio и позволить Вам видеть, где он происходит, тип исключительной ситуации, и т.д.

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

  1. синтаксический анализатор на самом деле не выдает исключение
  2. , синтаксический анализатор в конечном счете бросает что-то, что не происходит из Системы. Исключение
  3. существует исключение, бросаемое на другой поток, который не обрабатывается

, Это кажется на потенциальное исключение выпуска № 3.

1
ответ дан Scott Dorman 26 November 2019 в 21:20
поделиться

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

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

Добавляют этот код к Вашему grammer (.g) файл. Необходимо будет также выключить, "Включают Просто Мой Код" в меню отладки.

@members {

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

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

Это - моя попытка версии C# примера, данного в "Выходе из устройства распознавания на первой ошибке" глава "Категорической Ссылочной" книги ANTLR.

Hope это - то, что Вы искали.

2
ответ дан Dave Turvey 26 November 2019 в 21:20
поделиться

Я загрузил Ваш код, и все работает как ожидалось.

отладчик Visual Studio правильно прерывает все исключения. Блоки выгоды работают как ожидалось.

я выполняю сервер Windows 2003 SP2, Комплект Команды VS2008 (9.0.30729.1 SP)

, я пытался скомпилировать Вас проект для.NET 2.0, 3,0 & 3.5

@Steve Steiner, параметры отладчика, которые Вы упомянули, не имеют никакого отношения к этому поведению.

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

2
ответ дан aku 26 November 2019 в 21:20
поделиться

Я загрузил демонстрационный проект 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
            {
                alt4 = dfa4.Predict(input);
            }
            catch
            {
            }

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

2
ответ дан Scott Nichols 26 November 2019 в 21:20
поделиться

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

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

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

, Что, кажется, проблема здесь?

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

2
ответ дан angry person 26 November 2019 в 21:20
поделиться

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

одно время я видел это прежде, я работал с библиотекой, которая также определила Исключение и использования, я подразумевал, что фактическая Выгода относилась к различному типу "Исключения" (если это было полностью определено, это была Компания. Lib. Исключение, но это не было из-за использования), поэтому, когда это пришло к ловле нормального исключения, которое выдавалось (некоторое исключение аргумента, если бы я помню правильно), это просто не поймало бы его, потому что тип не соответствовал.

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

РЕДАКТИРОВАНИЕ: быстрый способ проверить это, удостоверяются в Вашем пункте выгоды, Вы полностью определяете Тип исключительной ситуации как "Система. Исключение" и дает ему водоворот!

EDIT2: хорошо я попробовал код и признаю поражение на данный момент. У меня должен будет быть другой взгляд на него утром, если никто не предложил решение.

2
ответ дан Shaun Austin 26 November 2019 в 21:20
поделиться

мне, выгода (Исключение) пункт должен был получить любое исключение вообще. Есть ли какая-либо причина, почему она не была бы?

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

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

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

2
ответ дан Steve Steiner 26 November 2019 в 21:20
поделиться

Я с @Shaun Остином - пытаются обернуть попытку с полностью определенным именем

catch (System.Exception)

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

3
ответ дан JamesSugrue 26 November 2019 в 21:20
поделиться

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

3
ответ дан Daniel Auger 26 November 2019 в 21:20
поделиться

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

http://www.netfxharmonics.com/2005/10/net-20-trycatch-and-trycatchexception/

5
ответ дан tbreffni 26 November 2019 в 21:20
поделиться

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

я согласился бы с Daniel, предполагает, что, возможно, исключение происходит на отдельном потоке - пытаются сцепить событие исключения потока в Приложении. ThreadException. Это должно быть повышено, когда любое необработанное исключение потока происходит. Вы могли адаптировать свой thus:-

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;
 }
кода
8
ответ дан ljs 26 November 2019 в 21:20
поделиться

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

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

Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);

 // Catch all unhandled exceptions in all threads.
 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
1
ответ дан Kibbee 26 November 2019 в 21:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: