Я использую версию Delphi (Delphi 10.2u2)
Моя цель - поиграть с веб-сервисом для обработки многопоточных команд GET, POST через платформу Indy, ничего сложного, и все работает нормально доЯ закрываю приложение во время запроса.
Для этого я использую TidHTTPClient для обработки команд и TIdSSLIOHandlerSocketOpenSSL для поддержки шифрования трафика.
Для многопоточности я использую TTask из библиотеки параллельного программирования (PPL).«Я совершенно новичок в использовании этой библиотеки с Delphi.»
Вот пример кода:
procedure TForm3.Button1Click(Sender: TObject);
begin
TTask.Create(
procedure
var HTTP : TidHTTP;
SSL : TIdSSLIOHandlerSocketOpenSSL;
content : String;
begin
HTTP := TIdHTTP.Create(nil);
SSL := TIdSSLIOHandlerSocketOpenSSL.create(nil);
SSL.SSLOptions.Method := sslvSSLv23;
HTTP.IOHandler := SSL;
HTTP.ConnectTimeout := 20000;
HTTP.ReadTimeout := 60000;
HTTP.HandleRedirects := true;
try
{
If we close the application during the Get, it raise an exception.
This is because the SSL Library is freed before the get has the time to stop
finalization
UnLoadOpenSSLLibrary(); // called before get is over
}
Content := HTTP.Get('https://www.google.com/');
TThread.Synchronize(nil, procedure begin
memo1.text := Content;
end);
except
// ...
on E : Exception do
TThread.Synchronize(nil, procedure begin
memo1.Text := 'Error';
end);
end;
SSL.Free;
HTTP.Free;
end).Start();
end;
Если вы скомпилируете и выполните этот код, вы увидите, что все просто работаетштраф до принятия решения о закрытии программы во время запроса (GET, POST или чего-либо еще)
Ошибка может варьироваться в зависимости от точного момента закрытия приложения во время HTTP-запроса.Это будет нарушение прав доступа, ошибка Winsock2 (WSA ...) и т. Д. *
Вот пример ошибки:
ПослеНемного поиска, я обнаружил, что ошибка была вызвана тем фактом, что требуемые библиотеки были освобождены до выполнения подпотоков.
Действительно, поскольку библиотеки SSL / Winsock (особенно) освобождаются во время незавершенного HTTP-запроса, непрерывностьзапроса вызовет некоторую недоступную функцию и вызовет исключение нулевого указателя, нарушение доступа и т. д. *
До использования TTasks я использовал обычные TThread, и все просто работало нормально, потому что на событии уничтожения приложения я ожидалвсе мои TThread выполнили свою задачу, прежде чем позволить процессу уничтожения продвинуться дальше.
Насколько я знаю, и я, вероятно, ошибаюсь, Delphi управляет этой частью, но, похоже, делает это после финализации Units.
Лучшим решением для меня было бы иметь возможность контролировать состояние моих заданий на событие уничтожениямоя программа нравится.Подождите, пока все мои задачи не завершат свои задачи.
НО, когда я не могу найти способ сделать это, не вызывая других видов исключений, таких как «Операция отменена»
procedure TForm3.FormDestroy(Sender: TObject);
begin
ATask.Cancel;
repeat
if ATask.Wait(500) = false then begin
CheckSynchronize();
end;
until (ATask = nil);
end;
Пример вышене будет работать ...
Я уверен, что я делаю что-то не так, я не мог найти какую-либо помощь, связанную с этой темой в другом месте, Delphi PPL звучит слишком много или моя проблема действительно необычна.
Заранее большое спасибо за вашу помощь.
Я действительно хочу использовать PPL для одного из моих крупнейших проектов, я не могу развернуть приложение с такими сообщениями об ошибках ^ _ ^
С уважением,