Похоже, что исключения, создаваемые в сборке выпуска, не перехватываются при обработке исключений:
Вот код и журналы, созданные при работе в сборках DEBUG и RELEASE:
try
{
Flog.Info("Force exception. Should be caught and logged next...");
object someObj = null;
someObj.GetType();
}
catch (Exception e)
{
Flog.Error(e); // Log error
}
Вот журнал в разделе RELEASE BUILD:
[2024-08-26][18:50:01.0863]:INFO:Force an exception. Should be caught and logged next...
// (and nothing else logged - app crashes)
В разделе ОТЛАДКА...
[2024-08-26][18:56:07.0897]:INFO:Force exception. Should be caught and logged next...
[2024-08-26]
[18:56:11.0326]:ERROR:DescriptionModels.DescriptiveText:Object reference not set to an instance of an object....
ТАК... понятно, что при сборке RELEASE исключения не перехватываются. ПОЧЕМУ ЭТО? Есть ли какой-то переключатель компилятора?
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ И МИНИМАЛЬНЫЙ ПРИМЕР:
По ссылке ниже находится ZIP-файл с решением и проектом, демонстрирующим эту проблему.
Запустите выпускную сборку проекта «TestException». Вы увидите две кнопки: одна вызывает исключение нулевой ссылки, а другая запускает фоновый поток, который отправляет запрос ping раз в секунду, используя класс NetworkInformation.Ping.
Нажмите кнопку, чтобы вызвать исключение несколько раз. При перехвате исключения вы увидите всплывающее предупреждение, сообщающее о нулевой ссылке.
Затем нажмите кнопку, чтобы запустить фоновый поток Ping.
После запуска этого потока нажмите кнопку, чтобы снова вызвать исключение. На этот раз вы увидите, что приложение просто завершает работу. Обработчик исключений никогда не вызывается.
ПРИМЕЧАНИЕ. Для возникновения этой проблемы не обязательно должен быть запущен фоновый поток: его нужно запустить только один раз. Если оно было запущено один раз, а затем остановлено, проблема все равно возникнет, если вы снова создадите исключение.
Минимальный проект кода, демонстрирующий проблему
Обратите внимание, что эта проблема возникает ТОЛЬКО в RELEASE-сборках. В отладочных сборках этой проблемы НЕТ.
СО: Что в классе Ping вызывает эту проблему? ИЛИ... что не так с кодом, из-за которого проблема возникает только в релизных сборках?
Здесь зарегистрирована проблема на GitHub
ДРУГОЕ ОБНОВЛЕНИЕ:
Нет необходимости даже запускать фоновый поток. Просто вызов «Ping» вызовет проблему.
@Jianwei: Проблема не в регистрации ошибок, проблема в том, что обработка исключений в релизных сборках (отсутствует) отличается от отладочных. Приведенная выше последовательность кода — это все, что необходимо для иллюстрации ошибки. (Замените Debug.Writeline на нашу оболочку Flog)
@Jianwei: Я только что создал новый проект, чтобы воспроизвести это. Интересно, что в новом проекте НЕ наблюдается та же проблема, хотя пример кода тот же. Итак, вопрос: что может отличаться в реальном проекте, из-за чего исключения игнорируются в сборке выпуска? Есть идеи, что может вызвать это? Я изучил настройки проекта и не нашел реальных различий. Что мне следует искать?
Удалите файл bin и obj вашего предыдущего проекта, а затем запустите его, чтобы проверить, не обнаруживается ли исключение в сборке выпуска.
Привет, @JianweiSun-MSFT: Я попробовал это, но это не помогло. Что я сделал, так это создал новый пустой проект, проверил, перехватываются ли исключения [ ((object)null).GetType() to throw ], а затем скопировал ВЕСЬ код из исходного проекта в новый. В новом проекте нет проблем с перехватом исключений. Я также заметил, что в новом проекте получаю разные предупреждения компилятора. Это странно. Кажется, это другая версия компилятора? Или... разные настройки. Очень очень странно.
Я также заметил, что в новом проекте получаю разные предупреждения компилятора. Это странно. Кажется, это другая версия компилятора? Или... разные настройки. Да, по поводу VS, я тоже раньше сталкивался с некоторыми странными проблемами. Вы можете сообщить об этом в Сообществе разработчиков/Visual Studio.
БОЛЬШЕ ОБ ЭТОМ: Приложение имеет последовательность запуска в MainActivity перед отображением главной страницы. Это состоит из 1. получения разрешений, 2. выполнения тестов базы данных и конфигурации и 3. запуска сетевого монитора для проверки подключения к серверу. Я методично удалил каждую последовательность и обнаружил, что проблема с «нет подхвата» исчезла, если я удалил сетевой монитор! В сетевом мониторе я также удалил код, чтобы сузить область поиска. Похоже, что удаление небольшого количества кода для «пингования» конечной точки Интернета решило проблему. НЕ понимаю, как пинг может повлиять на обработку исключений. Есть какие-нибудь объяснения?
Это существует в новом проекте или в старом проекте?
@JianweiSun-MSFT: В новом проекте. У меня пока не было времени воспроизвести в старом проекте. Но вместо этого я попробую изолировать поведение в минимальном приложении типа «привет, мир», теперь, когда я знаю «триггер». Я обновлю....
@JianweiSun-MSFT: Я отредактировал исходное сообщение, включив в него ссылку на ZIP-файл с проектом, демонстрирующим проблему с минимальным количеством кода. Это надежно воспроизводит проблему при запуске в моей системе. Пожалуйста, попробуйте это на своем и дайте мне знать, если вы столкнетесь с той же проблемой. Спасибо.
Ну и как ответ:
понятно, что при сборке RELEASE исключения не перехватываются...
Создание нового пустого проекта и перемещение кода из исходного проекта в новый позволяет нормально ловить исключения в режиме выпуска и отладки.
Поначалу казалось, что это сработало. Теперь, после внесения некоторых изменений в такие параметры, как оптимизация размера и т. д. (отключение), проблема повторилась в новом проекте. У меня МНОГО опыта разработки программного обеспечения, но эта проблема очень странная, и ее трудно диагностировать. Я собираюсь применить противоположный подход: взять совершенно новый проект типа «привет, мир» и посмотреть, что мне нужно сделать, чтобы проблема появилась. Однако это определенно какая-то ошибка Мауи....
Об этом вы можете сообщить в выпуске MAUI на GitHub.
Это не «решение», но это действительно ответ.
Проблема здесь была связана с использованием класса System.Net.NetworkInformation.Ping. Вызов метода Ping() в этом классе каким-то образом «крадет» обработку исключений, так что последующие исключения не перехватываются — и ТОЛЬКО в сборках RELEASE.
Посмотрите это объяснение на GitHub
Удаление использования этого класса решило проблему.
Основная проблема должна быть темой другой темы.
Почему бы не использовать официальный метод для регистрации ошибок? И, пожалуйста, предоставьте минимальный воспроизводимый образец.