delphi使用多实例表单

时间:2013-04-03 13:09:27

标签: delphi ftp indy

我有一个FTP上传程序项目,它使用在运行时创建的表单开始上传到多个FTP服务器(使用Indy),我的问题如下(我真的需要你的帮助)。

在表单上,​​我就像这样放了一个IdFTP组件+一个上传按钮+名为FTPSrvAdrs和SrcFile + TrgFolder的公共属性:

type
  TFtpUploader = class(TForm)
    IdFTP: TIdFTP;
    StartUpload:TButton;
    UploadProgress:TProgressBar;
    procedure StartUploadClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    FFtpSrvAdrs:String;
    FSrcFile:String;
    FTargetFtpFld:String;
    Procedure StartMyUpload();
    procedure SetFtpAdrs(const value:string);
    procedure SetSrcFile(const value:string);
    procedure SetTargetFtpFld(const value:string);
    { Private declarations }
  public
    { Public declarations }
    property FtpAdrs:string read FFtpSrvAdrs write SetFtpAdrs;
    property SourceFile:string read FSrcFile write SetSrcFile;
    property TargetFtpFld:string read FTargetFtpFld write SetTargetFtpFld;
  end;

var
  FtpUploader: TFtpUploader;

implementation

  procedure TFtpUploader.StartUploadClick(Sender: TObject);
  begin
  StartMyUpload(); 
  end;

  procedure TFtpUploader.SetFtpAdrs(const value: string);
  begin
  FFtpSrvAdrs:=value;
  end;

  procedure TFtpUploader.SetSrcFile(const value: string);
   begin
   FSrcFile:=value;
  end;

  procedure TFtpUploader.SetTargetFtpFld(const value: string);
   begin
  FTargetFtpFld:=value;
   end;

   procedure TFtpUploader.StartMyUpload;
    var
    FtpUpStream: TFileStream;
    begin
      ftpUpStream:= TFileStream.create(FSrcFile, fmopenread)
     try
     with IdFTP do begin
      Host:= FFtpSrvAdrs;
      Username:='MyUserName';
      Password:='MyPassword';
    end;
    IdFTP.Connect(true, 1200)
    IdFTP.Passive:= true;
    IdFTP.ChangeDir(FTargetFtpFld)
    IdFTP.Put(ftpUpStream,FSrcFile, false);
   finally
   ftpUpStream.Free;
   end;
   end;


  procedure TFtpUploader.FormClose(Sender: TObject; var Action: TCloseAction);
  begin
  Action:=caFree;
  end;

此表格将在RunTime上创建(4次= 4个按钮将以这种方式单独启动:

在主要表格中我有这个程序:

    Procedure MainForm.UploadTo(FTPSrv,SrcFile,FtpTargetFld:String);
        var
         FUploadFrm:TFtpUploader;
         begin
          FUploadFrm:=TFtpUploader.Create(nil);
          if assigned(FUploadFrm) then
         begin
          FUploadFrm.FtpAdrs:=FTPSrv;
          FUploadFrm.SourceFile:=SrcFile;
          FUploadFrm.TargetFtpFld:=FtpTargetFld;
          FUploadFrm.Show;
         end;
         end;

        procedure MainForm.Button1Click(Sender: TObject);
         begin
        UploadTo('MyFtpSrv_1','MySrcFile_1','MyFtpTargetFld_1');
        end;

         procedure MainForm.Button2Click(Sender: TObject);
         begin
         UploadTo('MyFtpSrv_2','MySrcFile_2','MyFtpTargetFld_2');
         end;

// same with other 2 buttons

FtpUploader表单是创建/打开的(4个实例),问题是当我点击StartUpload按钮时,FTP上传过程没有在所有这4个实例上启动,但我要等待每个上传过程完成(完成)并且另一个将自动启动,这意味着并非所有上载进程都是同时启动的。

谢谢。

1 个答案:

答案 0 :(得分:1)

似乎你必须为一些非阻塞的在线库(基于事件或基于完成端口)更改Indy库,或者使程序多线程化(使用它自己的一堆问题,如用户单击按钮在流程进行过程中关闭表单20次,或者甚至在运行时关闭程序。

根据http://otl.17slon.com/book/doku.php?id=book:highlevel:async,它看起来像这样:

  TFtpUploader = class(TForm)
  private
    CanCloseNow: boolean;

...

  procedure TFtpUploader.FormClose(Sender: TObject; var Action: TCloseAction);
  begin
    if Self.CanCloseNow
       then Action := caFree
       else Action := caIgnore;
  end;

  procedure TFtpUploader.MyUploadComplete;
  begin
    Self.CanCloseNow := True;
    Self.Close;
  end;

  procedure TFtpUploader.StartMyUpload;
  begin
    Self.CanCloseNow := false;
    Self.Enabled := False;
    Self.Visible := True;
    Application.ProcessMessages;

Parallel.Async(
  procedure
    var
    FtpUpStream: TFileStream;
    begin
     ftpUpStream:= TFileStream.create(FSrcFile, fmopenread)
     try
      with IdFTP do begin
       Host:= FFtpSrvAdrs;
       Username:='MyUserName';
       Password:='MyPassword';
       Connect(true, 1200)
       Passive:= true;
       ChangeDir(FTargetFtpFld)

       // this does not return until uploaded
       // thus would not give Delphi a chance to process buttons 
       //    pressed on other forms.
       Put(ftpUpStream,FSrcFile, false);
     end; 
    finally
      ftpUpStream.Free;
    end;
   end
,
  Parallel.TaskConfig.OnTerminated(
    procedure (const task: IOmniTaskControl)
    begin
      MyUploadComplete;
    end;
);
end;

或者您可以使用更简单的AsyncCalls库http://andy.jgknet.de/blog/bugfix-units/asynccalls-29-asynchronous-function-calls/