Конференция "Сети" » Проблема с InternetCloseHandle [D7, WinXP]
 
  • АндрейНН (01.06.10 12:22) [0]
    Здравствуйте, пытаюсь с помощью функций WinInet закачать файл на ftp-сервер, делаю это так:

    function TWinInetFTP.Put(Source, Dest, FileName: string; CreateFolder: boolean): boolean;
    var FileStream: TFileStream;
    begin
     Result := false;
     if FileName = '' then FileName := ExtractFileName(Source);
     try
       FileStream := TFileStream.Create(Source, fmOpenRead, 0);
       try
         Result := Put(FileStream, Dest, FileName, CreateFolder)
       finally
         FileStream.Free
       end
     except
       SetError('Put', 'File stream read error', GetLastError)
     end
    end;

    function TWinInetFTP.Put(Stream: TStream; Dest, FileName: string;
     CreateFolder: boolean): boolean;
    var
     TotalBytesWrite, BytesToWrite, BytesWrite: dword;
     buf: array of char;
    begin
     Result    := false;
     Terminate := false;
     BytesWrite      := 0;
     TotalBytesWrite := 0;
     Stream.Position := 0;
     // здесь создание директории если это необходимо
     if Dest[1] <> '/' then Dest := '/' + Dest;
     if Dest[Length(Dest)] <> '/' then Dest := Dest + '/';
     if not SetCurDir(Dest) then
       if not CreateFolder then
         begin
         SetError('Put', 'SetCurDir', GetLastError);
         Exit
         end
       else if not MakeDir(Dest) then Exit;
     // дальше собсно действия для выгрузки файла
     hFile := FtpOpenFile(hConnect, PChar(FileName), GENERIC_WRITE, 0, 0);
     if not Assigned(hFile) then
       SetError('Put', 'FtpOpenFile', GetLastError)
     else
       try
         SetLength(buf, BufferSize - 1);
         with Stream do
         repeat
           Application.ProcessMessages;
           if Terminate then Exit;
           Seek(TotalBytesWrite, soFromBeginning);
           BytesToWrite := BufferSize;
           if BytesToWrite > Size - Position then BytesToWrite := Size - Position;
           ReadBuffer(buf[0], BytesToWrite);
           if not InternetWriteFile(hFile, @buf[0], BytesToWrite, BytesWrite)
           then
             begin
             SetError('Put', 'InternetWriteFile', GetLastError);
             Break
             end;
           TotalBytesWrite := TotalBytesWrite + BytesWrite;
           if Assigned(FOnTransferEvent) then FOnTransferEvent(Self, Stream.Position)
         until Position = Size;
         Stream.Position := 0;
         Result := true
       finally
         buf := nil;
         MainForm.RichEdit.Lines.Append('Перед InternetCloseHandle');
         if not InternetCloseHandle(hFile) then {error} ;
         { на InternetCloseHandle виснет, то есть управление уже не возвращает }
         MainForm.RichEdit.Lines.Append('После InternetCloseHandle')
       end;
     MainForm.RichEdit.Lines.Append('Выход из процедуры \"Put (Stream)\"')
    end;



    То есть вызываю процедуру Put с именем файла в параметре, которая вызывает второй Put, обёртки для функций WinInet были сделаны для удобства (часто его использую + чтобы было хоть внешне похоже на Indy). Проблема в следующем - в день копируется достаточно много файлов, и примерно один раз на каждые 2000-3000 тысячи файлов программка зависает на вызове InternetCloseHandle (то бишь даже ошибку узнать не могу), в инете нашёл предложение как вариант использовать асинхронные вызовы и устанавливать свой таймаут на выполнение процедуры, но связываться с асинхронными вызовами не хотелось бы тем более что синхронные вполне устраивют кроме непонятного периодического зависания InternetCloseHandle.

    Подскажите плиз что ещё можно попробовать и в чём в принципе может быть загвоздка?
  • Плохиш © (01.06.10 23:20) [1]

    > в инете нашёл предложение


    > Подскажите плиз что ещё можно попробовать

    Типа, это опрос такой бессмысленный?
 
Конференция "Сети" » Проблема с InternetCloseHandle [D7, WinXP]
Есть новые Нет новых   [134436   +25][b:0][p:0.002]