Delphi ICS HTTPCLI自由异常

Delphi ICS HTTPCLI自由异常,delphi,delphi-xe2,Delphi,Delphi Xe2,当我使用这样的循环创建组件时,如何正确地释放它?如果我像现在一样释放它,我会得到一些GETMEM.INC异常。我来自印度,所以我对ICS了解不多 谢谢 const URLs : array[0..3] of string = ( 'http://www.example.com', 'http://www.example.com', 'http://www.example.com', 'http://www.example.com

当我使用这样的循环创建组件时,如何正确地释放它?如果我像现在一样释放它,我会得到一些GETMEM.INC异常。我来自印度,所以我对ICS了解不多

谢谢

  const
    URLs : array[0..3] of string =
    (
      'http://www.example.com',
      'http://www.example.com',
      'http://www.example.com',
      'http://www.example.com'
    ) ;

    var
      Output: array of TStringList;
      S: array of TMemoryStream;
      Async: array of TSslHttpCli;
    implementation

    procedure RequestDone(Sender: TObject; RqType: THttpRequest;
      ErrCode: Word);
    begin
        with Sender as TSSLHTTPCLI do  begin
          S[Tag].Position:=0;
          Output[Tag].LoadFromStream(S[Tag]);
        end;
      end;


    procedure TForm1.Button1Click(Sender: TObject);
    var
    i:integer;
    begin
        for i := 0 to High(URLS) do begin
           S[i]:=TMemoryStream.Create;
           Output[i]:=TStringList.Create;
           Async[i]:=TSslHttpCli.Create(nil);
           Async[i].Tag:=i;
           Async[i].FollowRelocation:=true;
           Async[i].NoCache:=true;

           Async[i].SocketFamily:=sfAny;
           Async[i].OnRequestDone:=RequestDone;
           Async[i].RcvdStream:=S[i];
           Async[i].URL:= URLs[i];
           Async[i].MultiThreaded:=true;
           Async[i].GetASync;
        end;
    end;

    procedure TForm1.Button4Click(Sender: TObject);
    var
    i:integer;
    begin
        for i := 0 to High(URLS) do begin
           Output[i].Free;
           Async[i].RcvdStream.Free;
           Async[i].Free; // << -- EXCEPTION
           //  S[i].Free;
        end;
    end;
const
URL:字符串的数组[0..3]=
(
'http://www.example.com',
'http://www.example.com',
'http://www.example.com',
'http://www.example.com'
) ;
变量
输出:TStringList数组;
S:TMemoryStream的数组;
Async:TSslHttpCli的数组;
实施
过程RequestDone(发送方:TObject;RqType:THttpRequest;
错误代码:Word);
开始
将发送方作为TSSLHTTPCLI开始
S[Tag]。位置:=0;
输出[Tag].LoadFromStream(S[Tag]);
结束;
结束;
程序TForm1.按钮1单击(发送方:TObject);
变量
i:整数;
开始
对于i:=0到高(URL)的情况,请不要开始
S[i]:=TMemoryStream.Create;
输出[i]:=TStringList.Create;
异步[i]:=TSslHttpCli.Create(nil);
异步[i]。标记:=i;
异步[i]。FollowRelocation:=true;
Async[i].NoCache:=true;
Async[i].SocketFamily:=sfAny;
异步[i].OnRequestDone:=RequestDone;
异步[i].RcvdStream:=S[i];
异步[i].URL:=URL[i];
异步[i]。多线程:=true;
异步[i].GetASync;
结束;
结束;
程序TForm1.按钮4点击(发送方:TObject);
变量
i:整数;
开始
对于i:=0到高(URL)的情况,请不要开始
输出[i]。自由;
异步[i].RcvdStream.Free;

异步[i]。免费;// 您从不为
结果
异步
S
分配任何内存。您需要对每一个文件进行
SetLength
,然后才能将任何文件放入其中(或取出任何文件)

顺便说一句,
Result
对于变量来说是个糟糕的名字,尤其是在作用域中是全局的变量。它是编译器自动生成的函数的返回值,在函数之外的任何地方使用都会使代码难以读取。例如,请参见:

var
  Result: string = '';

procedure AddToReslt(CharToAdd: Char);
begin
  // Many many lines of code
  // go in here. Maybe a few loops
  // of if statements.
  Result := Result + CharToAdd;
end;

function DoSomeMath: Integer;
begin
  // Some really complex numeric code, maybe
  // calculating the value of `pi` to the 900th
  // digit 
  Result := 2 * 2;
end;

现在,请记住它们中的每一个都包含大量代码,哪一个是函数,哪一个是过程?

当然是第二个。。过程没有结果:)我应该将其命名为输出。不是结果hehe:)为什么不使用
TList
来保存Http客户端?您可以创建
TMemoryStream
例如
Async[i].RcvdStream:=TMemoryStream.create
并且您可以在
RequestDone
内部释放
RcvdStream
,而不需要并行数组。重新考虑代码和变量名。这真是一团糟。@kobik你为什么不把它作为答案贴出来呢?很难理解你的意思..你在之前的Q中最初提供的链接中做得相当好。
var
  Result: string = '';

procedure AddToReslt(CharToAdd: Char);
begin
  // Many many lines of code
  // go in here. Maybe a few loops
  // of if statements.
  Result := Result + CharToAdd;
end;

function DoSomeMath: Integer;
begin
  // Some really complex numeric code, maybe
  // calculating the value of `pi` to the 900th
  // digit 
  Result := 2 * 2;
end;