小编VGe*_*iev的帖子

多线程文件上载同步

目前我正在使用Delphi XE3客户端/服务器应用程序来传输文件(使用Indy FTP组件).客户端部分监视文件夹,获取内部文件列表,将它们上载到服务器并删除原始文件.上传由一个单独的线程完成,该线程逐个处理文件.文件的范围从0到几千,它们的大小也有很大差异.

它是为OSX和Windows编译的Firemonkey应用程序,因此我不得不使用TThread而不是OmniThreadLibrary,这是我更喜欢的.我的客户报告该应用程序随机冻结.我无法复制它,但由于我对TThread没有那么多经验,我可能会把死锁条件放在某处.我读了很多例子,但我仍然不确定一些多线程的细节.

应用程序结构很简单:
主线程中的计时器检查文件夹并将每个文件的信息获取到记录中,该记录进入通用TList.此列表保留有关文件名称,大小,进度,文件是完全上载还是必须重试的信息.所有显示在带有进度条等的网格中.此列表仅由主线程访问.之后,通过调用AddFile方法(下面的代码)将列表中的项目发送到线程.该线程将所有文件存储在一个线程安全的队列中,如下所示http://delphihaven.wordpress.com/2011/05/06/using-tmonitor-2/
上传文件时,上传者线程通知主线程调用同步.
主线程定期调用Uploader.GetProgress方法来检查当前文件进度并显示它.这个函数实际上不是线程安全的,但它可能导致死锁,还是只返回错误的数据?

什么是安全有效的进度检查方法?

那么这种方法还可以,或者我错过了什么?你会怎么做?
例如,我虽然只是为了阅读文件夹内容而创建一个新线程.这意味着我使用的TList必须是线程安全的,但必须始终访问它以刷新GUI网格中显示的信息.不是所有的同步都会降低GUI的速度吗?

我已经发布了下面的简化代码,以防有人想看一下.如果没有,我会很高兴听到一些关于我应该使用的一般意见.主要目标是在OSX和Windows上工作; 能够显示有关所有文件的信息和当前文件的进度; 并且无论文件的数量和大小如何都要响应.

这是上传者线程的代码.我删除了一些以便于阅读:

type
  TFileStatus = (fsToBeQueued, fsUploaded, fsQueued);
  TFileInfo = record
    ID: Integer;
    Path: String;
    Size: Int64;
    UploadedSize: Int64;
    Status: TFileStatus;
  end;

  TUploader = class(TThread)
  private
    FTP: TIdFTP;
    fQueue: TThreadedQueue<TFileInfo>;
    fCurrentFile: TFileInfo;
    FUploading: Boolean;
    procedure ConnectFTP;
    function UploadFile(aFileInfo: TFileInfo): String;
    procedure OnFTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
    procedure SignalComplete;
    procedure SignalError(aError: String);
  protected
    procedure Execute; override;
  public
    property Uploading: Boolean read FUploading;
    constructor Create;
    destructor Destroy; …
Run Code Online (Sandbox Code Playgroud)

delphi macos upload multithreading firemonkey

18
推荐指数
1
解决办法
2128
查看次数

TOpenDialog/NSOpenPanel无法在沙盒Delphi应用程序中工作

Firemonkey应用程序中的TOpenDialog似乎存在问题,该应用程序是为Mac Appstore沙箱化的.我使用XE3,但它也存在于XE2中.我实际上在这里找到了QC报告,但它仍然没有得到解决:

http://qc.embarcadero.com/wc/qcmain.aspx?d=105344

有没有人有同样的问题,或任何想法如何解决它?

这很容易检查.只需在表单上放置一个TOpenDialog并调用Execute方法即可.根据Embarcadero说明对应用程序进行签名和沙箱:

http://docwiki.embarcadero.com/RADStudio/en/Mac_OS_X_Application_Development

当调用Execute时有一个延迟,应用程序冻结片刻,但没有显示任何内容.没有例外或错误消息.如果应用程序没有沙盒,则对话框可以正常工作.

此代码也不起作用,因此问题可能在TNSOpenPanel中的某个地方,由TOpenDialog调用,但遗憾的是我无法找到它.

var
  LOpenDir: NSOpenPanel;
begin
  LOpenDir := TNSOpenPanel.Wrap(TNSOpenPanel.OCClass.openPanel);
  LOpenDir.runModal;
  LOpenDir.release;
Run Code Online (Sandbox Code Playgroud)

我在Apple文档中读到,与没有沙箱的沙盒相比,使用Sandbox时,NSOpenPanel来自不同的类.我想这就是问题的原因.

任何想法将不胜感激.我们无法真正发布一个必须使用没有打开/保存对话框的文件的应用程序:)

顺便说一句,我尝试了项目选项中的权利的几种组合,但它们没有效果.

delphi macos sandbox firemonkey delphi-xe3

7
推荐指数
1
解决办法
987
查看次数