Приложение C RAD 2010 RTL/VCL -> Функция Terminate() НЕ ЗАВЕРШАЕТ ПРИЛОЖЕНИЕ

У меня также есть проблема, описанная здесь: http://www.delphigroups.info/3/9/106748.html

Я пробовал почти все формы размещения функции Application- > Terminate() везде в коде, следуя, а не «return 0», «ExitProcess (0)», «ExitThread (0)», exit (0). Ни один рабочий вариант не закрывает приложение. Вместо этого выполняется код после оператора Application->Terminate().

У меня есть два или более потока в приложении. Я попытался вызвать функцию завершения в созданных после выполнения потоках и в основном потоке.

Также это не связано (насколько я могу себе представить) с CodeGuard/madExcept (я выключал и включал, никакого эффекта). Включение CodeGuard также не увенчалось успехом.

Единственный рабочий вариант кода — поместить вызов Application->Terminate() в любой из обработчиков OnClick любой кнопки формы. Но это не соответствует моим потребностям. Мне нужно закончить в любом месте.

Что мне нужно сделать, чтобы завершить все потоки в приложении C++ Builder 2010, а затем завершить процесс?


person ergey    schedule 21.04.2010    source источник


Ответы (1)


Приложение->Завершить() не закрывает приложение немедленно, это только сигнализирует о том, что вы хотите закрыть приложение.

Terminate вызывает функцию Windows API PostQuitMessage для корректного завершения работы приложения. Отмена невозможна немедленно.

В ваших функциях вызовите Application->ProcessMessages() затем проверьте, не соответствует ли приложению >Terminated имеет значение true.

Для приложений, использующих циклы с интенсивными вычислениями, периодически вызывайте ProcessMessages, а также проверяйте Terminated, чтобы определить, следует ли прервать вычисление и разрешить завершение приложения.

Например:

void Calc()
{
  for (int x = 0; x < 1000000; ++x)
  {
    // perform complex calculation

    // check if need to exit
    Application->ProcessMessages();
    if (Application->Terminated)
    {
      break;
    } // end if
  } // end for

  // clean up
} 
person stukelly    schedule 21.04.2010
comment
Но какие условия должны быть соблюдены? Я жду закрытия приложения около 2 минут, и ничего не происходит. - person ergey; 22.04.2010
comment
Я обнаружил, что единственный способ действительно завершить мою программу в любом месте — это вызвать следующую последовательность: FormDestroy(); // также любые свободные блоки памяти, которые я поместил сюда TerminateProcess(GetCurrentProcess(), 0) - person ergey; 24.04.2010
comment
@ergey Я расширил свой ответ примером. - person stukelly; 28.04.2010
comment
Спасибо! Это действительно исправляет дело. Теперь я завершаю через App->Terminate(), затем в цикле вызываю ProcessMessages() и проверяю наличие флага Terminated, а затем возвращаюсь из дочернего потока. Но мне интересно, когда действительно RTL устанавливает этот флаг? После завершения основного потока или отключения только VCL/RTL? Но если они это сделают, я теоретически не смогу вызвать какие-либо функции stdlib/stdio, потому что RTL не работает, или есть другое значение флага завершения. - person ergey; 29.04.2010
comment
@ergey. Из справки: ProcessMessages устанавливает Terminated в true, когда получает сообщение WM_QUIT. - person stukelly; 29.04.2010