如何并行运行TTask多次?

时间:2019-05-31 12:17:33

标签: delphi

我有一个简单的方法,该方法使用TTask方法来执行长时间的操作,以调用数据快照服务器。

下面的方法可以完成工作:

procedure AssignPhoto(PhotoName, Folder: string; Image: TImage);
var
   Server: TSMClient;
   Size: Int64;
begin
  Server := TSMClient.Create(dmDados.DSRestConnection1);
  Size := 0;
  TTask.Run(
  procedure
  var
    PhotoStream: TStream;
  begin
    { 1. Long time operation calls datasnap to get a stream }
    PhotoStream := Server.DownloadFile(PhotoName, Folder, Size);

    { 2. Get the result in the UI Thread and display the picture }
    TThread.Synchronize(nil,
    procedure
    begin
      Image.Picture.LoadFromStream(PhotoStream);
      FreeAndNil(Server);
    end);

  end);
end;

如您所见,这只是调用数据快照服务器来获取TStream图片,并将其加载到作为参数传递的TImage中。

该方法效果很好,但是问题是:如果我两次调用此方法,它将无法正常工作。

我两次调用此方法来加载用户的个人资料照片和用户的身份证照片,如下代码所示。

  if FUrlProfile <> '' then
    AssignPhoto(FUrlProfile, PROFILE_PHOTO, imgProfile);
  if FUrlDoc <> '' then
    AssignPhoto(FUrlDoc, DOC_PHOTO, imgDoc);

这将打开一个表单并将图片加载到两个TImage组件中。

  1. 我第一次打开表单时效果很好;

  2. 当我尝试再次打开表单时。第二次尝试打开表单时出现错误:

ENetHTTPRequestException with message 'Error adding header: (87) Incorrect Parameter'

我知道,

  1. 如果我只加载一张图片,那么它一直都能正常工作。
  2. 如果我打开表单,请关闭并再次快速打开,这会导致错误。
  3. 如果我打开表单,请关闭,等待一会儿再重新打开它不会导致错误。它表明需要先完成一些工作,然后才能再次启动procedure

所以问题是它接缝不能多次调用TTask方法。也许我想念什么吗?

1 个答案:

答案 0 :(得分:1)

@J ...他的评论是正确的。问题是因为我在多个线程中使用了相同的TDSRestConnection

因此,每次创建方法时都创建一个TDSRestConnection是解决方案。

procedure AssignPhoto(PhotoName, Folder: string; Image: TImage);
var
  Server: TSMClient;
  Size: Int64;  
  DSRestConnection: TDSRestConnection;
begin
  DSRestConnection := GetConnection; // Creates a new TDSRestConnection
  Server := TSMClient.Create(DSRestConnection);
  Size := 0;
  TTask.Run(
  procedure
  var
    PhotoStream: TStream;
  begin
    { 1. Long time operation calls datasnap to get a stream }
    PhotoStream := Server.DownloadFile(PhotoName, Folder, Size);

    { 2. Get the result in the UI Thread and display the picture }
    TThread.Synchronize(nil,
    procedure
    begin
      Image.Picture.LoadFromStream(PhotoStream);
      FreeAndNil(Server);
    end);

  end);
end;

function GetConnection: TDSRestConnection;
begin
  Result := TDSRestConnection.Create(nil);
  Result.Host := SERVER_HOST;
  Result.Port := SERVER_PORT;
end;