2012-03-25 6 views
5

Tôi đã cố gắng tải lên +100 tệp để cộng với Delphi. Tuy nhiên, các cuộc gọi chặn chủ đề chính, vì vậy tôi muốn làm điều này với một cuộc gọi không đồng bộ hoặc với một chủ đề nền.Cách tải tệp lên azure trong nền với Delphi và OmniThread?

Đây là những gì tôi làm bây giờ (như 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; 

Tuy nhiên khối này quá (tại sao tôi không hiểu?).

Trả lời

4

này khối vì bạn đang gọi WAITFOR mà đợi cho tất cả các giai đoạn đường ống để kết thúc công việc của họ. Trong thời gian chờ đợi, GUI bị chặn.

Một cách thích hợp để làm điều đó là

  1. cửa hàng giao diện trở về từ Parallel.Pipeline trong một lưu trữ toàn cầu (ví dụ như trong một lĩnh vực TCloudManager).
  2. Lập lịch công việc cho đường ống.
  3. Đừng đợiĐối với kết thúc nhưng chỉ định trình xử lý OnStop và thực hiện bất kỳ việc dọn dẹp nào bạn cần ở đây (đừng quên không lưu trữ toàn bộ lưu trữ giao diện đường ống).

Để thực hiện bước 3, bạn sẽ cần OmniThreadLibrary tươi từ SVN vì tôi vừa mới thêm chức năng này :)

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; 
+0

Rất vui được gặp bạn ở đây. Là đường ống đúng công cụ cho điều này? – mamcx

+0

Không thực sự. Tôi sẽ chỉ làm một Parallel.ForEach. – gabr

+0

Tôi cũng thử với Parallel.ForEach, nhưng tôi cần phải chèn Application.ProcessMessages() và không phải là chất lỏng. Có lẽ vì sự thiếu hiểu biết của tôi về việc sử dụng thư viện ... – mamcx

-5

Delphi có biến thể .NET, phải không? Bạn có biết có một .NET Managed API cho dịch vụ lưu trữ Azure không?

Lớp CloudBlockBlob có một biến thể async để tải lên/tải vv

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

+0

Vâng, đó là tồn tại, nhưng tôi cần điều này trong delphi bản địa. – mamcx

+2

-1. Điều này hoàn toàn không liên quan gì đến câu hỏi được yêu cầu ở đây và không nên đăng câu trả lời. –

+0

Ken - làm thế nào để bạn tìm ra? Nếu anh ta sử dụng Delphi.NET tôi đã cho anh ta một thư viện mà là đúng vào mục tiêu - khả năng tải lên rất nhiều tập tin không đồng bộ. – sebastus