【问题标题】:Application taking a really long time to synch threads ( or not at all )应用程序需要很长时间来同步线程(或根本不同步)
【发布时间】:2014-04-14 21:32:36
【问题描述】:

我在 Delphi XE5(iOS 和 Android)中使用 REST 组件。我目前正在通过 iOS 模拟器进行测试,而我的应用程序经常挂在我的代码中的以下行:

R_Request.Execute;

经过一些调试,我发现它特别挂在 REST.Client.PAS 中的这行代码:

HandleEvent(DoAfterExecute);

看起来像:

procedure TCustomRESTRequest.HandleEvent(AEventHandler: TMethod);
begin
  // Handle Synchronized if we are NOT already in the main thread
  // NEVER call synchronize on the MainThread - that might shift the island!
  if SynchronizedEvents and (System.MainThreadID <> TThread.CurrentThread.ThreadID) then
    TThread.Synchronize(TThread.CurrentThread, AEventHandler) // FAILS HERE
  else
    AEventHandler;
end;

要么没有返回 .Synchronize 中的线程,要么花费了很长时间(5 分钟左右)...... 它在调试时工作了一次,但从那以后就再也没有了(30 分钟后,让它设置 5 分钟后返回一个线程)。

帮助?或者至少任何人都可以给我任何方向感?

再次,为 iOS 和 Android 开发(所以 FMX...),目前正在通过 iOS 模拟器进行测试。 谢谢 !

【问题讨论】:

    标签: multithreading delphi delphi-xe5


    【解决方案1】:

    问题是 TThread.Synchronize() 在 FireMonkey 中被破坏了。请参阅此 QC 报告:

    Report #123579: TThread.Synchronize() and TThread.Queue() do not work correctly in FireMonkey

    这只是最近才被发现,但自从 FireMonkey 首次推出以来它就被打破了,直到现在才明显没有人注意到。

    在 Embarcadero 修复它之前,尝试在主线程中定期调用 CheckSynchronize(),例如在计时器中。

    【讨论】:

    • 是的,我发现的时候吓了一跳,而且由于不同平台处理主线程,没有好办法手动实现WakeMainThread()以跨平台的方式“唤醒”主线程事件队列不同。至少CheckSynchronize() 本身是跨平台的,但是让 RTL 调用它是一个 PITA,除非你自己调用它。
    • 窝!不过感谢 CheckSynch。建议。
    • @Hans,真的解决了吗?因为当我尝试在 android 上的 TThread.Execute 范围内执行此 self.Synchronize(procedure begin BusyForm.Show end); 时,它会返回可怕的异常 CalledFromWrongThreadException: 只有创建视图层次结构的原始线程才能触及其视图 建议在 Android Studio 中通过 runOnUiThread 方法运行 UI 更新来解决。这意味着它在XE8 中仍然存在问题。任何意见表示赞赏。
    • @notricky 这是一个完全不同的问题。 Synchronize() 本身现在已修复,因此它执行用户的功能。您遇到的是一个新问题,即 FMX 主线程和 Android UI 线程并不总是同一个线程!计划在下一个 Delphi 版本中解决这个问题。同时,FMX.Platform.Android.TPlatformAndroid 类有一些通过runOnUIThread() 执行函数的方法。
    • @RemyLebeau,我的问题很简单。至于TPlatformAndroid,它隐藏在单元的实现部分,但给出了一些思考(我想它可以在跨平台的基础上解决问题),我在FMX.Android.Helpers 里面找到了一个不错的proc CallInUIThreadAndWaitFinishing这可以解决问题。所以我只需要 {$IFDEF}。与往常一样,我对言论持开放态度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-30
    相关资源
    最近更新 更多