Einzelnen Beitrag anzeigen

Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.766 Beiträge
 
Delphi 10.4 Sydney
 
#26

Re: Indy 10 - Progressbar arbeitet nicht mehr mit OnWork

  Alt 28. Jul 2006, 17:58
Das ist ein Auszug aus IdIOHandler vom letzen Snapshot von Indy 10.
Wie man sieht ist dort das buffering auskommentiert.
Herbert hat das ja auf andere Weise gelöst.

Delphi-Quellcode:
procedure TIdIOHandler.Write(AStream: TIdStream; ASize: Int64 = 0;
  AWriteByteCount: Boolean = FALSE);
var
  LBuffer: TIdBytes;
  LBufSize: Integer;
  // LBufferingStarted: Boolean;
begin
  if ASize < 0 then begin //"-1" All form current position
    LBufSize := AStream.Position;
    ASize := AStream.Size;
    //todo1 is this step required?
    AStream.Position := LBufSize;
    ASize := ASize - LBufSize;
  end
  else if ASize = 0 then begin //"0" ALL
    ASize := AStream.Size;
    AStream.Position := 0;
  end;

  //else ">0" ACount bytes
  EIdIOHandlerRequiresLargeStream.IfTrue((ASize > High(Integer)) and (not LargeStream));

  // RLebeau 3/19/2006: DO NOT ENABLE WRITE BUFFERING IN THIS METHOD!
  //
  // When sending large streams, especially with LargeStream enabled,
  // this can easily cause "Out of Memory" errors. It is the caller's
  // responsibility to enable/disable write buffering as needed before
  // calling one of the Write() methods.
  //
  // Also, forcing write buffering in this method is having major
  // impacts on TIdFTP, TIdFTPServer, and TIdHTTPServer.

  {
  LBufferingStarted := not WriteBufferingActive;
  LBufferingStarted := False;

  if LBufferingStarted then begin
    WriteBufferOpen;
  end;
  }


  //try
    if AWriteByteCount then begin
      if LargeStream then begin
         Write(ASize);
      end else begin
         Write(Integer(ASize));
      end;
    end;

    BeginWork(wmWrite, ASize);
    try
      while ASize > 0 do begin
        SetLength(LBuffer, FSendBufferSize); //BGO: bad for speed
        LBufSize := Min(ASize, FSendBufferSize);
        // Do not use ReadBuffer. Some source streams are real time and will not
        // return as much data as we request. Kind of like recv()
        // NOTE: We use .Size - size must be supported even if real time
        LBufSize := TIdStreamHelper.ReadBytes(AStream, LBuffer, LBufSize);
        if LBufSize = 0 then begin
          raise EIdNoDataToRead.Create(RSIdNoDataToRead);
        end;
        SetLength(LBuffer, LBufSize);
        Write(LBuffer);
        // RLebeau: DoWork() is called in TIdIOHandlerStack.WriteDirect() <---------------
        //DoWork(wmWrite, LBufSize); <--- vielleicht wenn es nicht laufen sollte, hier doWork wieder aktivieren.
        Dec(ASize, LBufSize);
      end;
    finally
      EndWork(wmWrite);
      LBuffer := nil;
    end;
  {
    if LBufferingStarted then begin
      WriteBufferClose;
    end;
  except
    if LBufferingStarted then begin
      WriteBufferCancel;
    end;
    raise;
  end;
  }

end;
Nun der Auszug aus idIOHandlerStack:
Delphi-Quellcode:
procedure TIdIOHandlerStack.WriteDirect(var ABuffer: TIdBytes);
var
  LCount: Integer;
  LPos: Integer;
  LSize: Integer;
begin
  inherited WriteDirect(ABuffer);

  Assert(Binding<>nil);

  LSize := Length(ABuffer);
  LPos := 0;
  repeat
    LCount := Binding.Send(ABuffer, LPos, LSize - LPos);
    // TODO - Have a AntiFreeze param which allows the send to be split up so that process
    // can be called more. Maybe a prop of the connection, MaxSendSize?
    TIdAntiFreezeBase.DoProcess(False);
    FClosedGracefully := LCount = 0;

    // Check if other side disconnected
    CheckForDisconnect;
    DoWork(wmWrite, LCount);
    Inc(LPos, LCount);
  until LPos >= LSize;
end;
Wo der aufgerufen wird ist mir aber nicht ersichtlich.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat