0

我有一个时间关键的过程,将 JPG 图像(大约 10 张照片,每张大约 150KB)发送到 Web 服务器。在发送时,我想让用户执行其他操作,例如输入或选择其他数据,以加快整个过程。

我已经尝试过线程,但没有经验,所以我的第一次尝试是最好的情况 - 一样。否则,德尔福挂断等...

_____________________________________________________________________
procedure DoOnCameraGrabFoto(iID:integer; pic: TPicture; iTyp: Byte; ts: TDateTime);
const
  SVC_AddFoto2Master='';
var
  req: TIdMultiPartFormDataStream;
  blob: TStream;
begin
  with dtsBlobs.DataSet do begin
    // At first add images to local dataset, just to see them...
    Append;
    FieldByName('MasterID').Value:=iID;
    FieldByName('DateAndTime').Value := ts;
    FieldByName('PhotoType').Value := iTip;

    blob:=CreateBlobStream((FieldByName('FotoObj') as TBlobField), bmWrite);
    try
      pic.Graphic.SaveToStream(blob);


      ////////////////////////////////////////////////////
      //
      //  POST foto to server with Indy (Delphi 7)
      //
      req:=TIdMultiPartFormDataStream.Create;
      try
        req.AddFormField('iMasterID', IntToStr(iID));
        req.AddFormField('iTyp' , IntToStr(iTip));
        req.AddFormField('tsPhoto' , DateToSqlDate(ts, false)+ ' ' + TimeToStr(ts));
        req.AddObject('oFoto', 'image/jpeg', blob, 'photo' );


        // Folowing method do something like shown below
        // ExecPostRequest('http://server:80/svcWebServiceThatPostData', req);
        //
        // ... and there is no problem when there are only one foto or two.
        // But, when there is lot a fotos, in this meantime, operator can for example
        // fill-out the form, or something else.
        //
        //
         IdHTTP1.Request.ContentType:=req.RequestContentType;
         result:=IdHTTP1.Post(sUrl, req);
      finally
        req.Free;
      end;
      //
      ///////////////////////////////////////////////////////
    finally
      blob.Free;
    end;
    Post;
  end;
4

1 回答 1

2

如果您试图使此代码使用工作线程,请尝试以下操作:

type
  TPostThread = class(TThread)
  private
    fUrl: string;
    fID: Integer
    fStrm: TStream;
    fTyp: Byte;
    fTs: TDateTime;
  protected
    procedure Execute;
  public
    constructor Create(Url: string; ID: Integer; Strm: TStream; Typ: Byte; Ts: TDateTime); reintroduce;
    destructor Destroy; override;
  end;

constructor TPostThread.Create(Url: string; ID: Integer; Strm: TStream; Typ: Byte; Ts: TDateTime);
begin
  inherited Create(False);
  FreeOnTerminate := True;
  fUrl := Url;
  fID := ID;
  fStrm := Strm;
  fTyp := Typ;
  fTs := Ts;
end;

destructor TPostThread.Destroy;
begin
  fStrm.Free;
  inherited;
end;

procedure TPostThread.Execute;
var
  http: TIdHTTP;
  req: TIdMultiPartFormDataStream;
begin
  http := TIdHTTP.Create;
  try
    req := TIdMultiPartFormDataStream.Create;
    try
      req.AddFormField('iMasterID', IntToStr(fID));
      req.AddFormField('iTyp' , IntToStr(fTyp));
      req.AddFormField('tsPhoto', DateToSqlDate(fTs, False) + ' ' + TimeToStr(fTs));
      req.AddFormField('oFoto', 'image/jpeg', '', fStrm, 'photo');

      http.Post(fUrl, req);
    finally
      req.Free;
    end;
  finally
    http.Free;
  end;
end;

procedure DoOnCameraGrabFoto(iID:integer; pic: TPicture; iTyp: Byte; ts: TDateTime);
var
  img, blob: TStream;
begin
  img := TMemoryStream.Create;
  try
    pic.Graphic.SaveToStream(img);
    img.Position := 0;

    with dtsBlobs.DataSet do begin
      Append;
      try
        FieldByName('MasterID').Value := iID;
        FieldByName('DateAndTime').Value := ts;
        FieldByName('PhotoType').Value := iTyp;

        blob := CreateBlobStream(FieldByName('FotoObj'), bmWrite);
        try
          blob.CopyFrom(img, 0);
        finally
          blob.Free;
        end;

        Post;
      except
        Cancel;
        raise;
      end;
    end;

    strm.Position := 0;
    TPostThread.Create(sUrl, iID, img, iTyp, ts);
    img := nil;
  except
    img.Free;
    raise;
  end;
end;
于 2013-09-21T00:37:24.543 回答