Proble z thread wraz z urldownload

0

witam, pisze aplikacje która ma siągać pliki z internetu z podanego url oraz nazwy pliku do zapisu. Wszytko to robię na thread ale coś nie działa jak trzeba. Plik się sciąga ale po wyjsciu z thread, aplikacja się zacina i nie można utworzyć kolejnego threadu i wyskakuje błąd w stylu 'EaccessViolation at adress 00401cfe in module applikacja.exe' . Podaje kod threadu... może mi ktoś pomoże jak zrobić poprawnie ściąge plików na thread... Pozdrawiam i z góry dzięki.

 

function GetInetFile ( fileURL, FileName: String): boolean;
const BufferSize = 1024;
var
  hSession, hURL: HInternet;
  Buffer: array[1..BufferSize] of Byte;
  BufferLen: DWORD;
  f: File;
  sAppName: string;
begin
Result:=False;
 sAppName := ExtractFileName(Application.ExeName);
 hSession := InternetOpen(PChar(sAppName),
                INTERNET_OPEN_TYPE_PRECONFIG,
               nil, nil, 0);
 try
  hURL := InternetOpenURL(hSession,
            PChar(fileURL),
            nil,0,0,0);
  try
   AssignFile(f, FileName);
   Rewrite(f,1);
   repeat
    InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen);
    BlockWrite(f, Buffer, BufferLen)
   until BufferLen = 0;
   CloseFile(f);
   Result:=True;
  finally
   InternetCloseHandle(hURL)
  end
 finally
  InternetCloseHandle(hSession)
 end
end;


      //http://kamil.barlinek.biz/altcmd/altcmd_setup.exe
procedure UrlDownloadThread (Thread: TThread); //(const URL: String; FileName: String; gMode : boolean ; Uid: cardinal );

var
  Buffer : array[1..1024] of Byte; // bufor zawierający ściągnięty fragment pliku
  hSession, hURL : HINTERNET;
  dwRead : DWORD; // ilość odczytanych danych
  dwSize : DWORD;  // rozmiar pliku
  dwSizeD : DWORD;  // sciagniety rozmiar pliku
  F : File;
  pBuf : Pointer;
  dwBufLen : DWORD;
  dwIndex : DWORD;
  TotalRead  : Integer;
  //
  Terminated: boolean;
   Socket1: TServerSocket;
  CmdBuffer: TMemoryStream;
  Header: urlh;
   Done : boolean;
   ss: string ;
begin
   Terminated := False;
   Done := false ;
   //http://download.speedbit.com/dap90.exe//

    Socket1 := TServerSocket(Thread.Data);
   CmdBuffer := TMemoryStream(Socket1.Socket.Data);

  //  CmdBuffer := TMemoryStream(Thread.Data);
    CmdBuffer.Position := 0;
    CmdBuffer.ReadBuffer(Header, SizeOf(urlh));


 if (( Header.url_source = '' ) or (Header.url_file  = '' )) then Done:= true;

      ss := 'URL not download.'  ;

  while ( (not Terminated) and (not Done ) ) do
  begin
    Thread.Lock;
    try
      Terminated := Thread.Terminated;
    finally
      Thread.Unlock;
    end;
    if Terminated then Break;
    Sleep(100);
  
    try

    try
    if GetInetFile ( Header.url_source  ,  Header.url_file )  then
    begin
       ss := 'URL Download succesful!' ;
    end
    else
    begin
        ss := 'URL Error while downloading.'  ;
    end;
    except
    end;
 
      finally

        Done := true ;
        Terminated := true ;
  

       Thread.Lock;

            if Header.url_mode then
               Form1.gSendMsg(Header.url_uid, 95,ss,'1')
             else
               SendMsgThr(Socket1, 95, ss);
 

             Thread.Unlock;

      end; //finaly




  end; //while

 CmdBuffer.Free;
 Thread.Free;

 

end;


// tu jest kod tworzenia threadu --------------------------------

             Header2.url_source := url;
             Header2.url_file := filepath ;
             Header2.url_mode := false ;
             Header2.url_uid := 0;


                    CmdBuffer := TMemoryStream.Create;
                    CmdBuffer.WriteBuffer(Header2, SizeOf(urlh));
                    UrlDownload := TThread.Create(@UrlDownloadThread, CREATE_SUSPENDED);
                   // UrlDownload.Data := CmdBuffer;// Socket;
                    ServerSocket1.Socket.Data :=  CmdBuffer ;
                    UrlDownload.Data := ServerSocket1 ;//CmdBuffer;// Socket;

                    ResumeThread(UrlDownload.ThreadHandle);
//----------------------------------------------------------


0

podaj CAŁY kod klasy wątku

0

to co podalem wczesniej jest w tform1, a tu podaje kod threadu z pliku uThread.pas.
tworzenie threadu jest robione z procedury tform1.createNewtread ( url , filepath... )
tak jak wczesniej podalem :

Header2.url_source := url;
Header2.url_file := filepath ;
Header2.url_mode := false ;
Header2.url_uid := 0;
....

 
unit uThread;

interface

uses Windows;

type
  TThread = class;

  TThreadProcedure = procedure(Thread: TThread);

  TSynchronizeProcedure = procedure;

  TThread = class
  private
    FThreadHandle: longword;
    FThreadID: longword;
    FExitCode: longword;
    FTerminated: boolean;
    FExecute: TThreadProcedure;
    FData: pointer;
  protected
  public
    constructor Create(ThreadProcedure: TThreadProcedure; CreationFlags: Cardinal);
    destructor Destroy; override;
    procedure Synchronize(Synchronize: TSynchronizeProcedure);
    procedure Lock;
    procedure Unlock;
    property Terminated: boolean read FTerminated write FTerminated;
    property ThreadHandle: longword read FThreadHandle;
    property ThreadID: longword read FThreadID;
    property ExitCode: longword read FExitCode;
    property Data: pointer read FData write FData;
  end;

implementation

var
  ThreadLock: TRTLCriticalSection;

procedure ThreadWrapper(Thread: TThread);
var
  ExitCode: dword;
begin
  Thread.FTerminated := False;
  try
    Thread.FExecute(Thread);
  finally
    GetExitCodeThread(Thread.FThreadHandle, ExitCode);
    Thread.FExitCode := ExitCode;
    Thread.FTerminated := True;
    ExitThread(ExitCode);
  end;
end;

constructor TThread.Create(ThreadProcedure: TThreadProcedure; CreationFlags: Cardinal);
begin
  inherited Create;
  FExitCode := 0;
  FExecute := ThreadProcedure;
  FThreadHandle := BeginThread(nil, 0, @ThreadWrapper, Pointer(Self), CreationFlags, FThreadID);
end;

destructor TThread.Destroy;
begin
  inherited;
  CloseHandle(FThreadHandle);
end;

procedure TThread.Synchronize(Synchronize: TSynchronizeProcedure);
begin
  EnterCriticalSection(ThreadLock);
  try
    Synchronize;
  finally
    LeaveCriticalSection(ThreadLock);
  end;
end;

procedure TThread.Lock;
begin
  EnterCriticalSection(ThreadLock);
end;

procedure TThread.Unlock;
begin
  LeaveCriticalSection(ThreadLock);
end;

initialization
  InitializeCriticalSection(ThreadLock);

finalization
  DeleteCriticalSection(ThreadLock);

end.


0

wytłumacz mi, tak jakbyś do noba to mówił - dlaczego nie weźmiesz klasy TThread i nie zrobisz tego po ludzku albo jak już bardzo chcesz to nie zrobisz BeginThread(.., TU_PROCEDURA_KTORA_BEDZIE_URUCHAMIANA_W_OSOBNYM_WATKU,..), ew. nie skorzystasz z jakichś gotowych rozwiązań (np. OmniThreadLibrary) tylko kombinujesz z jakimiś dziwnymi konstrukcjami, które ani nie są łatwe do debugowania a i jak widać nie działają za dobrze

1 użytkowników online, w tym zalogowanych: 0, gości: 1