Delphi로 HTTP 서버를 만들었습니다. 서버 응답 시간을 테스트하기 위해 임의의 URL을 생성하는 http 클라이언트 애플리케이션을 만들었습니다. 문제는 내가 서버의 요청을 처리하기 시작한 부분을 처리하는 것입니다. 여기에 내 코드의 일부는 다음과 같습니다HTTP 클라이언트 요청 받기
procedure TPerformanceTestForm.ExecuteURLs;
var
requests: array of TRequestBuilder;
i: Integer;
Stopwatch: TStopwatch;
Elapsed: TTimeSpan;
begin
SetLength(requests, 10);
EnterCriticalSection(criticalSection);
Stopwatch := TStopwatch.StartNew;
for i := 0 to Length(requests) - 1 do
begin
requests[i] := TRequestBuilder.Create;
end;
// remove this lines from source in order to execute all threads
// for i := 0 to Length(requests) - 1 do
// begin
// requests[i].Terminate;
// end;
Elapsed := Stopwatch.Elapsed;
Seconds := Elapsed.TotalSeconds;
LeaveCriticalSection(criticalSection);
end;
procedure TPerformanceTestForm.btnStopQueriesClick(Sender: TObject);
var
i: Integer;
begin
for i := 0 to Length(requests) - 1 do
begin
// requests[i].WaitFor; // the program crashes
requests[i].Free;
end;
end;
이 TRequestBuilder 클래스의 일부입니다 :
이 절차는 요청을 전송하기 시작하는 실행중인
TRequestBuilder = class(TThread)
private
fHttpClient: TIdHTTP;
public
Constructor Create; reintroduce;
procedure Execute; override;
end;
Constructor TRequestBuilder.Create;
begin
inherited Create(False); // in order not to start another loop and call start for each instance
// FreeOnTerminate := True; // removed this line; see the first answer to know why
Self.fHttpClient := TIdHTTP.Create;
// HttpWorkBegin and HttWork I get from the first answer
Self.fHttpClient.OnWorkBegin := HttpWorkBegin;
Self.fHttpClient.OnWork := HttpWork;
end;
procedure TRequestBuilder.Execute;
var
request, response: string;
begin
repeat
try
request := GenerateHttpRequest;
response := Self.fHttpClient.Get(request);
log.AddJob(request + ' ---> ' + response + ' ---> ' +
FormatDateTime('dd.mm.yyyy hh:mm:ss', Now));
except
on e: Exception do
begin
errlog.Add(FormatDateTime('dd.mm.yyyy hh:mm:ss', Now) + ' ---> ' +
e.Message);
end;
end;
until (Terminated);
end;
// EDIT: change Execute procedure to avoid socket errors (removed the httpClient from class variables):
procedure TRequestBuilder.Execute;
var
request, response: string;
httpClient: TIdHTTP;
begin
repeat
try
httpClient := TIdHTTP.Create;
try
request := GenerateHttpRequest;
response := httpClient.Get(request);
log.AddJob(request + ' ---> ' + response + ' ---> ' +
FormatDateTime('dd.mm.yyyy hh:mm:ss', Now));
finally
httpClient.Free;
end;
except
on e: Exception do
begin
errlog.Add(FormatDateTime('dd.mm.yyyy hh:mm:ss', Now) + ' ---> ' +
e.Message);
end;
end;
until (Terminated);
end;
** 편집 : ** 언제 http 클라이언트를 중지하십시오.이 오류가 발생합니다. App.exe 모듈의 주소 004083A0에서 액세스 위반. 주소 FFFFFFFC의 읽기.
** EDIT : ** ExecutreURLs에서 두 번째 for 루프가 제거되었으므로 프로그램이 제대로 작동합니다 (예외가 발생하는 경우도 있음). 내 질문은 지금 : ExecuteURLs 프로 시저에서 요청을 종료하지 않으면 메모리 누수가 발생합니까?
** 편집 : ** Execute 프로 시저에서 repeat- until 루프를 제거하면 프로그램이 올바르게 작동합니다 (첫 번째 편집의 예외 만 발생 함). repeat- until 루프를 추가하고 btnStopQueries onclick 이벤트에서 제거하면 여러 소켓 오류가 발생합니다.
? 좀 더 구체적이어야합니다. –
@RemyLebeau 오류가 OnFormDestroy에 있었는데 해결했지만 질문을 업데이트하지 않았습니다. –