5

I have tried to upload +100 files to azure with Delphi. However, the calls block the main thread, so I want to do this with a async call or with a background thread.

This is what I do now (like 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;

However this block too (why? I don't understand).

4

2 に答える 2

4

これは、すべてのパイプライン ステージが作業を完了するのを待機する WaitFor を呼び出しているため、ブロックされます。その待機中、GUI はブロックされます。

それを行う適切な方法は

  1. Parallel.Pipeline から返されたインターフェイスをグローバル ストレージ (TCloudManager フィールドなど) に格納します。
  2. 作業をパイプラインにスケジュールします。
  3. WaitFor end ではなく、OnStop ハンドラーを割り当て、ここで必要なクリーンアップを実行します (パイプライン インターフェイスを保持するグローバル ストレージを nil アウトすることを忘れないでください)。

ステップ 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;
于 2012-03-26T06:03:46.530 に答える
-5

Delphi には .NET バリアントがありますよね?Azure Storage Service 用の .NET マネージ API があることをご存知でしたか?

CloudBlockBlob クラスには、アップロード/ダウンロードなどの非同期バリアントがあります。

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

于 2012-03-25T21:09:50.873 に答える