如何使用Delphi和OmniThread将文件上传到背景中?

时间:2012-03-25 20:26:23

标签: multithreading delphi azure delphi-xe2 omnithreadlibrary

我尝试使用Delphi将+100文件上传到azure。但是,这些调用会阻塞主线程,因此我希望通过异步调用或后台线程执行此操作。

这就是我现在所做的事情(如explained here):

procedure TCloudManager.UploadTask(const input: TOmniValue;
  var output: TOmniValue);
var
  FileTask:TFileTask;
begin
  FileTask := input.AsRecord<TFileTask>;

  Upload(FileTask.BaseFolder, FileTask.LocalFile, FileTask.CloudFile);
end;

function TCloudManager.MassiveUpload(const BaseFolder: String;
  Files: TDictionary<String, String>): TStringList;
var
  pipeline: IOmniPipeline;
  FileInfo : TPair<String,String>;
  FileTask:TFileTask;
begin
  // set up pipeline
  pipeline := Parallel.Pipeline
    .Stage(UploadTask)
    .NumTasks(Environment.Process.Affinity.Count * 2)
    .Run;
  // insert URLs to be retrieved
  for FileInfo in Files do
  begin
    FileTask.LocalFile := FileInfo.Key;
    FileTask.CloudFile := FileInfo.Value;
    FileTask.BaseFolder := BaseFolder;

    pipeline.Input.Add(TOmniValue.FromRecord(FileTask));
  end;//for

  pipeline.Input.CompleteAdding;

  // wait for pipeline to complete
  pipeline.WaitFor(INFINITE);
end;

然而这块也是(为什么?我不明白)。

2 个答案:

答案 0 :(得分:4)

这会阻塞,因为您正在调用WaitFor,等待所有管道阶段完成其工作。在等待期间,GUI被阻止。

正确的方法是

  1. 从Parallel.Pipeline返回的商店界面在全局存储中(例如在TCloudManager字段中)。
  2. 安排管道工作。
  3. 不要等待结束,而是分配OnStop处理程序并在此处执行所需的清理工作(不要忘记忽略管道接口的全局存储)。
  4. 要执行第3步,您需要SVN中新的OmniThreadLibrary,因为我刚添加了此功能:)

    procedure TCloudManager.MassiveUpload(const BaseFolder: String;
      Files: TDictionary<String, String>);
    var
      FileInfo : TPair<String,String>;
      FileTask:TFileTask;
    begin
      // set up pipeline
      FPipeline := Parallel.Pipeline
        .Stage(UploadTask)
          .NumTasks(Environment.Process.Affinity.Count * 2)
        .OnStop(
          procedure begin
            ShowMessage('All done');
            FPipeline := nil;
          end)
        .Run;
    //   insert URLs to be retrieved
      for FileInfo in Files do
      begin
        FileTask.LocalFile := FileInfo.Key;
        FileTask.CloudFile := FileInfo.Value;
        FileTask.BaseFolder := BaseFolder;
    
        FPipeline.Input.Add(TOmniValue.FromRecord(FileTask));
      end;//for
      FPipeline.Input.CompleteAdding;
    end;
    

答案 1 :(得分:-5)

Delphi有一个.NET变体,对吧?您是否知道Azure存储服务有一个.NET托管API?

CloudBlockBlob类具有上传/下载的异步变体等。

http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.windowsazure.storageclient.cloudblockblob_methods.aspx