2012-12-13 52 views
1

我怎樣才能正確地釋放組件,一旦我這樣做了一個循環?如果我像現在這樣釋放它,我會得到一些GETMEM.INC異常。我來自Indy,所以我不太瞭解ICS。ICS HTTPCLI免費例外

感謝

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; 
+2

爲什麼不使用'TList'來容納Http客戶端?你可以創建'TMemoryStream',例如'Async [i] .RcvdStream:= TMemoryStream.Create',並且你可以在'RequestDone'內部釋放'RcvdStream'而不需要並行數組。重新考慮你的代碼和變量名稱。一團糟。 – kobik

+0

@kobik你爲什麼不把它作爲答案發布?很難理解你的意思。 –

+0

你最初在Q中提供的鏈接中的[代碼示例](http://www.delphipages.com/forum/showthread.php?t=199517)確實很好。 – kobik

回答

2

你從來沒有分配任何內存爲ResultAsynch,或S。你需要每個人都有SetLength,然後你纔可以放入任何東西(或取出任何東西)。

procedure TForm1.Button1Click(Sender: TObject); 
var 
i:integer; 
begin 
    SetLength(Result, Length(URLS)); 
    SetLength(S, Length(URLS)); 
    SetLength(Asynch, Length(URLS)); 

    for i := 0 to High(URLS) do begin 
    S[i]:=TMemoryStream.Create; 
    Result[i]:=TStringList.Create; 
    Async[i]:=TSslHttpCli.Create(nil); 

    // etc. 

    end; 
end; 

BTW,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; 

現在快 - 記住他們每個人containss大量的代碼 - 這一個是功能,這是一個過程?

+0

Ofcourse第二個..程序沒​​有結果:)我應該命名爲Output。不是結果hehe :) –