0

JPG 画像 (約 10 枚の写真、それぞれ約 150KB) を Web サーバーに送信するタイムクリティカルなプロセスが 1 つあります。送信中に、プロセス全体を高速化するために、他のデータの入力や選択などの他のアクションをユーザーに許可したいと思います。

私はスレッドを試してみましたが、経験がありません。そのため、最初の試行は最善の場合でした-同じです。そうしないと、Delphi がハングアップします。

_____________________________________________________________________
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 に答える