MessageBox с тайм-аутом ИЛИ Закрытием MessageBox от другого потока

Если мои сбои приложения, я использую ExceptionFilter, чтобы поймать катастрофический отказ, выполнить некоторые окончательные решения, то покажите окно сообщения пользователю, что приложение отказало.

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

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

  • Любой MessageBox с тайм-аутом. Проблема состоит в том, что Вы не можете сделать этого со стандартной API-функцией MessageBox Win32, и я не хочу делать определенное диалоговое окно для нее (потому что я хочу минимизировать выполняемую логику после катастрофического отказа),
  • Или возможность закрыть MessageBox от другого потока (другой поток может обеспечить логику тайм-аута).

Я пропускал что-то в API Win32 и являюсь там возможностью иметь MessageBox с тайм-аутом?

Или что корректный путь состоит в том, чтобы закрыть открыть MessageBox от другого потока (как получить дескриптор MessageBox, как закрыть его...)?

5
задан Patrick 22 June 2010 в 08:04
поделиться

7 ответов

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

Однако возник другой вопрос: https://stackoverflow.com/questions/3091915/explanation-why-messagebox-of-exited-application-is-adopted-by-winsrv .

2
ответ дан 18 December 2019 в 10:42
поделиться

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

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

3
ответ дан 18 December 2019 в 10:42
поделиться

Хотя я согласен с тем, что порождение нового процесса для отображения диалога типа "забей и забудь", вероятно, лучше, FWIW на самом деле есть функция MessageBox с таймаутом, экспортируемая из user32 на XP и выше; MessageBoxTimeout (используется такими вещами, как WShell.Popup())

.
6
ответ дан 18 December 2019 в 10:42
поделиться

Это не оправдывает поток.

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

1
ответ дан 18 December 2019 в 10:42
поделиться

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

Вы можете закрыть свое приложение, закрыть сетевые соединения и сделать ваши домашние дела.

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

1
ответ дан 18 December 2019 в 10:42
поделиться

Win32 MessageBox на самом деле является диалоговым окном с насосом диалоговых сообщений. Поэтому вы можете полагаться на стандартные сообщения таймера Win32 (WM_TIMER). Отправьте его в собственное окно, а когда получите его, закройте MessageBox, отправив сообщение WM_COMMAND / BN_CLICKED кнопке ID_OK.

Окно сообщения, поскольку это диалог, будет иметь класс "# 32770". Поскольку это единственное открытое диалоговое окно, его легко найти среди дочерних окон.

1
ответ дан 18 December 2019 в 10:42
поделиться

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

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

0
ответ дан 18 December 2019 в 10:42
поделиться
Другие вопросы по тегам:

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