2015-04-16 2 views
5

ПРИМЕЧАНИЕ ДОБАВЛЕНО ПОСЛЕ РЕШЕНИЯ: В методе, вызванном отражением, было выбрано исключение AccessViolationException. Именно поэтому TargetInvocationException не удалось поймать.System.Reflection.TargetInvocationException не удаляется

ПРИМЕЧАНИЕ: Это ВНЕ ВИДЕО. The referenced question is NOT the same.

TL; DR

  1. Не удается получить трассировку стека
  2. Не удается получить внутренние исключения
  3. Невозможно использовать схему защиты отладчик (копия библиотеки третьей партии получает в пути)
  4. Любые изменения в коде предотвращают возникновение исключения - это означает, что я не могу добавить регистрацию, чтобы узнать, где произошло исключение

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

Длинное описание:

У меня возникли проблемы с исключением того, что происходит в методе, который вызывается с помощью отражения. Само исключение на самом деле происходит в вызываемом методе, но поскольку метод вызывается отражением, реальное исключение обернуто в System.Reflection.TargetInvocationException. Нет проблем, просто поймайте его и получите внутреннее исключение, за исключением того, что System.Reflection.TargetInvocationException не попадает. Моя программа сбой, и я получаю дамп вместе с записью в журнале событий Windows.

Журнал событий Windows не содержит внутренних исключений, а также дамп. Я не могу приложить отладчик к программе, потому что тогда внешняя библиотека (которая необходима для вызова отражения) не будет работать - защита от копирования, разве вы не знаете. Если я помещу try/catch в метод оскорбления, исключение не возникает - что плохо. Причина не исправлена, ее больше не бывает. Тот же эффект возникает, если я ввел запись в метод оскорбления - исключение больше не происходит.

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

Я использую Visual Studio 2010 и dotnet 4.0.

Чтобы было ясно: попытка/уловка не работает, когда программа запускается за пределами Visual Studio, и я не могу запустить ее внутри Visual Studio в отладчике, потому что тогда программа не может достичь где происходит исключение. Это НЕ в среде IDE.

Исключая отражение не вариант (я попробовал это для только в одном случае, и исключение уходит.)

Вызываемый метод делает много вещей, но разбить его на более мелкие методы не помогают - исключение просто исчезает.

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

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

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

В приведенном ниже коде представлена ​​упрощенная версия вызова путем отражения.

Есть ли у кого-нибудь предложение относительно того, что может вызвать System.Reflection.TargetInvocationException, чтобы не быть пойманным, или, может быть, альтернативным способом уловить внутреннее исключение?

Try 
    Dim methode As System.Reflection.MethodInfo 
    methode = GetType(AParticularClass).GetMethod("OneOfManyMethods", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static) 
    Dim resultobject As Object = methode.Invoke(Nothing, Reflection.BindingFlags.InvokeMethod Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static, Nothing, New Object() {SomeBooleanVariable, SomeStringVariable}, Nothing) 
    result = DirectCast(resultobject, DataSet) 
Catch ex As Exception 
    'Log the error here. 
End Try 
+0

Возможный дубликат [Почему объект TargetInvocationException рассматривается как непроверенный с помощью IDE?] (Http://stackoverflow.com/questions/2658908/why-is-targetinvocationexception-treated-as-uncaught-by-the-theide) –

+1

Не дубликат, потому что это происходит за пределами среды IDE. – JRE

+1

Это много текста, с очень маленькой информацией, которая позволила бы любому даже угадать причину. Нет трассировки стека. Нет кода, который на самом деле является частью вашей проблемы. Вы указываете, что вещи выполняются в потоках, но не показывают, как это сделать. Пожалуйста, укажите соответствующую информацию. – Alex

ответ

8

нашел причину, почему я не мог поймать исключение:

Фактическое исключение было AccessViolationException, которые не могут быть пойманы в Dotnet 4.0 без принятия специальных мер (How to handle AccessViolationException.)

Для сделать вещи более увлекательными, когда AccessViolationException получает бросок в методе, вызванном отражением, в журнале событий Windows регистрируется только TargetInvocationException, и в дампе доступно только исключение TargetInvocationException.

Как только мне удалось получить реальное исключение, я обнаружил, что это вызов Application.DoEvents() из потока без GUI, вызвавшего AccessViolation. DoEvents() может вызвать достаточно удовольствия при вызове GUI-Thread (Use of Application.DoEvents()), не говоря уже о вызове из фонового потока.

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

Код, вызывающий все это удовольствие, был когда-то в GUI-Thread, и был первоначально записан во времена dotnet 1.1 - это объясняет призыв к DoEvents. Код был преобразован по частям для параллельной работы в фоновом потоке через несколько разных этапов, причем ни один разработчик не имеет полного обзора процесса.

+0

Как вы в итоге отлаживали это? Мы видим ту же проблему, что и TIE в журнале событий Windows – ChaseMedallion

+0

Add Try/catch (если у вас его еще нет), следуйте инструкциям здесь (http://stackoverflow.com/a/4759831/ 3945058), чтобы включить исключения «поврежденного состояния». – JRE

+0

Привет, это кажется [моей проблемой тоже] (http://stackoverflow.com/q/39954552/1488067), я заметил «AccessViolationException» внутри журнала отчетов об ошибках Windows сразу после моего исключения. Одно не совсем ясно, если вы можете прояснить это: действительно ли ваше исключение произошло в точке, указанной с помощью трассировки стека, или это произошло в каком-то совершенно другом потоке и только что не удалось выполнить внутри вашего метода? Как вам удалось получить «реальное исключение»? – Lou

0

Я не уверен, что могу повторить свой вопрос, но это то, как мы получаем его, и он работает просто отлично ...

Try 
    'YOUR CODE' 
Catch ex As Exception 
    'This is where we grab it from... It needs to be in this block to work... 
    System.Reflection.MethodInfo.GetCurrentMethod.ToString 
End Try 

Позвольте мне знать, как это произведения для вас?

+0

Как я уже сказал, уловка не поймает ничего, программа просто падает. Все, что я получаю, это запись в журнале событий Windows, в которой говорится, что программа разбилась и сообщает мне, что это за исключение. – JRE

+0

Итак, это другой тип исключения, поэтому его не поймают ... Покажите, какой код находится в этом блоке ... – Codexer

+0

Невозможно, это несколько сотен строк и включает вызовы других методов. Древние грехи, которые я не совершал, но должны жить. Это также наиболее определенно System.Reflection.TargetInvocationException, но оно вызвано чем-то внутри отраженного метода. Тип не имеет значения, в любом случае - Catch ex as Exception должен улавливать все виды исключений. – JRE

Смежные вопросы