Вопрос № 99335: Доброе время суток эксперты!
Есть 2 вопроса:
1. Как отловить все ошибки для программы глобально?
Т.е. я делаю try catch в WinMain и по
catch (...) {
My_ShowException( );
}
вывожу. Но как отловить ошибку с текстом? Т.е....Вопрос № 99425: В программе создано 20 потоков, выполняющих сходные задачи (подключение к удаленному компьютеру через WMI). Всё работает нормально, загрузка процессора менее 10%. Но иногда приложение зависает, при этом загрузка процессора становится 100%, а у потоко...
Вопрос
№ 99.335
Доброе время суток эксперты!
Есть 2 вопроса:
1. Как отловить все ошибки для программы глобально?
Т.е. я делаю try catch в WinMain и по
catch (...) {
My_ShowException( );
}
вывожу. Но как отловить ошибку с текстом? Т.е. адрес, текст сообщения и т.п. штуки?
2. Почему если я 1 форме (не главной) поставил флаг поверх всех окон (fsstayontop) то если скрыть главную форму (ShowWindow ф-ия) то эта форма уже не поверх всех окон и её спокойно перекрывают другие. В чем парадокс?
Отвечает: Maxim V.G.
Здравствуйте, Уваров Андрей Александрович!
Блок try-catch обрабатывает не ошибки приложения либо выполнения функции, а исключительные ситуации. Например при попытки чтения информации из испорченного сектора диска, неверная информация, ошибка обращения к памяти, при ожидании числового значения из стандартного потока ввода-вывода поступает символьное значение - это искдлючительная ситуация и обрабатывается в вышеуказаном блоке. Но бывают и ошибки выполнения функции которые являются штатной ситуацией для приложения. Например при попытки открытия несуществующего
файла ф-ия fopen возвращает NULL. Это является результатом ошибки выполнения функции. API функции часто возвращают ошибки системы для просмотра и вывода пользователю которых используется функция GetLastError. Единственной угрозой, при возникновении таких ошибок, является некоректная работа приложения которая целиком и полностью лежит на плечах разработчика. Поэтому абсоютно все ошибки может отловить только разработчик тчательно обдумывая каждый фрагмент программы
на наличие ошибок и отражения ошибок на корректоной работе приложения! А универсального способа отловить все ошибки глобально существовать не может, так как никто кроме разработчика не знает как должна работать программа и что является ошибкой, а что штатной для приложения ситуацией!!!
--------- Жить вредно - от неё умирают
Ответ отправил: Maxim V.G. (статус: 3-ий класс)
Ответ отправлен: 23.08.2007, 01:10 Оценка за ответ: 1 Комментарий оценки: Отлично! Эти ошибки разработчика я и хочу отловить для отправки мне этих сообщений с ошибками. Системы репортинга. Не один раз видел, как это делают разные программы. Вы так и не ответили ни на один вопрос.
Отвечает: C4tnt
Здравствуйте, Уваров Андрей Александрович!
1. Для того, чтобы узнать описание ошибки используйте такой синтаксис:
try
{
// Ваш код
}
catch( CMemoryException* e )
{
// Обработка ошибок памяти
}
catch( CFileException* e )
{
// Обработка ошибок при работе с файлами
}
catch( CException* e )
{
// Обработка остального
}
catch( char *str )
{
// Обработка всего, что до сих пор не поймано :-)
// str содержит описание ошибки
}
Объект CException содержит следующие методы:
Delete - ликвидация объекта
int ReportError(
UINT nType = MB_OK, //Тип диалогового окна
UINT nMessageID = 0 //Идентифакатор строки из StringTable, которая будет показана если описание ошибки не найдено (если указать 0 - напишет "No error message is available")
);
- показать окно с сообщением об ошибке
GetErrorMessage(
LPTSTR lpszError, //указатель на строку, которая будет хранить сообщение
UINT nMaxError, //максимальная длинна строки
PUINT pnHelpContext = NULL //указатель для получения Help context ID (Идентификатор описания данной ошибки)
) - получить описание ошибки
Если у вас планируются серьёзные ошибки обращения к памяти :) , лучше использовать глобальный перехват ошибок:
SetUnhandledExceptionFilter(CurrentFilter) - устанавливает "общепрограммную" функцию, которая будет обрабатывать все ошибки.
CurrentFilter - указатель на функцию вида:
LONG WINAPI UnhandledExceptionFilter(
struct _EXCEPTION_POINTERS* ExceptionInfo
);
ExceptionInfo содержит кучу информации об ошибке
Функция должна вернуть одно из значений:
EXCEPTION_CONTINUE_SEARCH - ошибка не была устранена, пробуем стандартный обработчик ошибок.
EXCEPTION_EXECUTE_HANDLER - дать программе возможность обработать ошибку с помощью try...catch
!Важно!
SetUnhandledExceptionFilter возвращает укаатель на старый глобальный обработчик ошибок. При завершении работы программы его желательно восстановить.
По поводу вопроса №2. Используйте функцию
BOOL SetWindowPos(
HWND hWnd, - hwnd вашего окна
HWND hWndInsertAfter, - hwnd окна после которого вставляем ваше окно (здесь не используется) или флажок HWND_TOPMOST или HWND_NOTOPMOST соотвтственно
int X, - X координата
int Y, - Y координата
int cx, - Ширина
int cy, - Высота
UINT uFlags - Флаги
);
Собственно флаги:
SWP_NOMOVE - окно не двигаем, X и Y игнорируется
SWP_NOACTIVATE - окно не станет активным после вызова этой функции
SWP_NOSIZE - не меняем размер окна, cx и cy игнорируем
SWP_NOZORDER - не меняем расположения окна относительно других окон, hWndInsertAfter игнорируется
--------- Теперь к нашим ответам осталось лишь найти вопросы
Ответ отправил: C4tnt (статус: 3-ий класс)
Ответ отправлен: 26.08.2007, 19:27 Оценка за ответ: 5 Комментарий оценки: Вот это действительно хороший и развернутый ответ! Так держать! Побольше бы таких экспертов. Мега огромное спасибо!
Вопрос № 99.425
В программе создано 20 потоков, выполняющих сходные задачи (подключение к удаленному компьютеру через WMI). Всё работает нормально, загрузка процессора менее 10%. Но иногда приложение зависает, при этом загрузка процессора становится 100%, а у потоков число переключений контекста возрастает до 10-20 тысяч в секунду. То есть получается, что все потоки работают, но очень-очень медленно из-за переключений. В чем может быть проблема? Какой-то "плавающий" баг.
Отправлен: 23.08.2007, 16:26
Вопрос задал: Palpatin (статус: Посетитель)
Всего ответов: 1 Мини-форум вопроса >>> (сообщений: 1)
Отвечает: Dr.Alex
Здравствуйте, Palpatin!
Я работал с большим числом потоков и тоже было нечто подобное. И что обнаружил, если в потоковом глухом цикле while поставить Sleep(), даже на небольшое число миллисекунд, то этот глюк пропадает. Т.е. получается надо отдавать хоть немного времени ядру винды.
Ответ отправил: Dr.Alex (статус: 10-ый класс)
Ответ отправлен: 23.08.2007, 16:35 Оценка за ответ: 4 Комментарий оценки: У меня большинство потоков висят на функции WMI Connect(), пытаясь подключиться к выключенным компам. И циклов нет внутри потоков. Тяжко. :(