предположим, что у меня есть поток, который все еще работает, когда приложение завершается (Этот поток не может завершиться, потому что он ожидает возврата вызова API Windows, а это может быть долго. ) Что произойдет с потоком, если приложение будет закрыто? Может ли это вызвать исключение (у меня Delphi)?
задан 22 апр.
user382591
Хорошо, как ваше приложение завершается? Есть несколько способов сделать это. — David Heffernan
приложение.завершить; — user382591
Какую функцию Win32 API на самом деле использует ваш рабочий поток? Скорее всего, он предоставляет способ отмены функции, чтобы ваш рабочий поток мог корректно завершиться по запросу. Основной поток должен завершать рабочий поток перед выходом из процесса. — Remy Lebeau
1 ответы
- Звонок в PostQuitMessage .
- Application.Terminated установлен на True .
- Application.Run возвращение.
- System.Halt называется.
- Выполняются процедуры выхода, в частности DoneApplication который разрушит Application и все компоненты, которыми он владеет. Хм, лучше надейтесь, что ваш поток не получит доступ ни к чему, принадлежащему Application .
- FinalizeUnits называется. О-о. Диспетчер памяти закрыт, и многое другое.
- ExitProcess называется. Теперь ваша ветка убита.
Ваш поток будет продолжать работать до тех пор, пока вызов ExitProcess . Если он вообще выполнит какой-либо код, на который повлияют вызовы DoneApplication и FinalizeUnits , то следует ожидать проблем.
✅ Не запускается уже установленный Autocom 2020.23 ошибки запуска автоком
ответ дан 22 апр.
Да, обычно потому, что формы и, следовательно, используемая ими память исчезают до того, как ОС получает возможность остановить все потоки на шаге 7. Исключение «216» или «217», как правило, возникает. Я долгое время избегал этой проблемы, связываясь с формами только с помощью объектов PostMessaging, которые не принадлежат формам и, как правило, никогда явно не освобождаются. — Мартин Джеймс
Моя ветка не взаимодействует с формами. Он удаляет только некоторые файлы на сетевом диске (доступ к сетевым дискам может быть долгим. ) — user382591
Дескрипторы сетевых дисков будут закрыты ОС на шаге 7 после того, как все потоки вашего процесса будут остановлены, поэтому, опять же, вы должны быть в порядке. — Мартин Джеймс
Если он использует диспетчер памяти Delphi, у вас проблемы. Это идет в шаге 6. — Дэвид Хеффернан
Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками windows multithreading delphi or задайте свой вопрос.
Источник: stackovergo.com
Не завершается процесс программы
Есть пример программки с авторизацией, простейший.
Она, работает но проблема в том, что если откроется окно приветствие, то после закрытия его, форма закроется а приложение будит весеть в задачах.
урок на делфи 27. три способа закрыть программу.
В чем тут проблема?
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Button1: TButton; Label1: TLabel; Label2: TLabel; procedure Button1Click(Sender: TObject); private < Private declarations >public < Public declarations >end; var Form1: TForm1; Const login=’vasya’; pass=’pass’; implementation uses Unit2; procedure TForm1.Button1Click(Sender: TObject); begin if (Edit1.Text=login) and (Edit2.Text=pass) then begin Form2.Show; Form1.Visible:=false; end else ShowMessage(‘Ошибка!’); end; end.
unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm2 = class(TForm) Label1: TLabel; private < Private declarations >public < Public declarations >end; var Form2: TForm2; implementation end.
Вложения
TEST_app.zip (9.0 Кбайт, 0 просмотров) |
Источник: delphisources.ru
Завершить программу Delphi
У меня есть программа, которой нужны данные с SQL-сервера, без нее она работать не может (ну, может, но совершенно бесполезна).
В этом порядке есть две формы автосоздания: DMOD и основная.
Это код в OnCreate DMOD:
if not fileexists(UdlFile) then begin ITRCreateFile(UdlFile); ShellExecute(Application.Handle,’open’,UdlFile,nil,nil,SW_SHOW); try cnConnect.Close; if gServerPort <> » then cnConnect.connectionString:= ‘Provider=SQLOLEDB.1;Password=*;Persist Security Info=True;User Catalog=ExquisStudio;Data Source=’ + gServerName + » + gServerPort + ‘;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ;Use Encryption for Data=False;Tag with column collation when possible=False’ else cnConnect.connectionString:= ‘Provider=SQLOLEDB.1;Password=*;Persist Security Info=True;User Catalog=ExquisStudio;Data Source=’ + gServerName + ‘;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ;Use Encryption for Data=False;Tag with column collation when possible=False’; cnConnect.Open(); except Showmessage(‘Problems with dataconnection — error SQL data’); screen.Cursor := crDefault; Application.terminate; end; end else begin try cnConnect.Close; if gServerPort <> » then cnConnect.connectionString:= ‘Provider=SQLOLEDB.1;Password=*;Persist Security Info=True;User Catalog=ExquisStudio;Data Source=’ + gServerName + » + gServerPort + ‘;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ;Use Encryption for Data=False;Tag with column collation when possible=False’ else cnConnect.connectionString:= ‘Provider=SQLOLEDB.1;Password=*;Persist Security Info=True;User Catalog=ExquisStudio;Data Source=’ + gServerName + ‘;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ;Use Encryption for Data=False;Tag with column collation when possible=False’; cnConnect.Open(); except Showmessage(‘Problems with dataconnection — error SQL data’); screen.Cursor := crDefault; Application.terminate; end; end;
Проблема в том, что программа закрывается, ничего не остается видимого, но процесс продолжает работать, в основном при 95% или более высокой загрузке ЦП. Это не очень хорошо .
Я добавил ExitProcess(0); после обоих Application.terminate; , и теперь процесс завершается, как и должно быть. Я использовал 0, потому что параметр является обязательным, понятия не имею, каким он должен быть на самом деле.
У меня вопрос: можно ли так делать? Он делает то, что я хочу, но у меня такое чувство, что я что-то не замечаю.
diedie2 30 Апр 2014 в 13:33
Вероятно, это не очень хорошая идея. Если ваш процесс не завершается сам по себе, и вы не знаете почему, это означает, что ваша программа содержит ошибки. Использование ExitProcess(0) просто заметает это под ковер. Вы лечите симптомы, а не причину. Лучше отладьте свою программу и выясните, почему она не завершается, и устраните основную проблему.
30 Апр 2014 в 13:39
Вместо использования ShellExecute(,’open’ в файле .udl я настоятельно рекомендую импортировать «Библиотеку типов сервисных компонентов Microsoft OLE DB 1.0» (на машине, на которой я сейчас работаю, она определяется %CommonProgramFiles(x86)%SystemOle DBoledb32.dll ) и/или объект MSDASC , который позволит вам отображать диалоговое окно свойств связи данных в модальном режиме.
Stijn Sanders
30 Апр 2014 в 21:12
3 ответа
Лучший ответ
Хорошо, я думаю, что нашел.
Вот что я сделал:
- Я удалил Main из списка автосоздания форм, так что там остался только DMOD. Заметил, что программа действительно здесь зависает, если не было связи.
- Я удалил Application.terminate; в исключительных частях.
- Это код, который находится под кодом, который я опубликовал ранее. Это также код, который все еще выполнялся после того, как Application.terminate; был вызван в исключительной части. Я добавил здесь дополнительную проверку и также позвонил в Main, если все в порядке.
if cnConnect.Connected then begin ADOPermissions.Open; ADOGroupMembers.Open; ADOGroupAccess.Open; ADOGroups.Open; ADOUserAccess.Open; ADOUsers.Open; Application.CreateForm(TfrmMain, frmMain); end else Application.terminate;
Я чувствую себя немного глупо из-за того, что сам не обнаружил этого, используя точку останова, как сейчас, но я думал, что Application.terminate; остановит и убьет процесс напрямую.
TLama 30 Апр 2014 в 16:23
Хм, удалив Main как форму по умолчанию, теперь файл .dproj открывается, когда я открываю проект в RAD Studio вместо Main. Есть ли способ изменить это?
2 Май 2014 в 11:13
ExitProcess завершит ваш процесс. Но за счет того, что нужно провести надлежащую уборку. На самом деле вам следует выяснить, почему программа не закрывается. Что работает, что мешает выключению? Эту информацию невозможно отличить от кода в вопросе.
Вам нужно будет копнуть немного глубже.
Если вы не можете работать с нашим статическим анализом, вы можете использовать отладчик, чтобы помочь:
- Запустите вашу программу под отладчиком.
- Выполните действие, вызывающее Application.Terminate .
- Приостановите выполнение с помощью Run | Program Pause .
- Посмотрите состояние потоков с помощью View | Debug Windows | Threads .
- Дважды щелкните поток, чтобы выбрать его и просмотреть стек вызовов.