RestClient 和线程锁定

RestClient and thread locking

使用 Delphi 10.4

使用工具 REST 调试器,调用了一个 API,并获得了组件。

使用

调用组件
begin
  writeln('starting');
    RESTRequest1.Execute; writeln('finieshed 1');
    RESTRequest2.Execute; writeln('finieshed 2');
    RESTRequest3.Execute; writeln('finieshed 3');
  writeln('Done.');

end;

当我调试代码时

并且在执行中有一行

  // Eventhandlers AFTER Observers
  HandleEvent(DoAfterExecute);

这导致程序:

class procedure TThread.Synchronize(const AThread: TThread; AMethod: TThreadMethod);
var
  LSynchronize: TSynchronizeRecord;
begin
  LSynchronize.Init(AThread, AMethod);
  Synchronize(@LSynchronize); // <--- here
end;

密码锁定。

我认为它是一个死锁,但是我不知道锁的是什么。

设置是控制台应用程序中的一个线程。

Download := TDownload.Create(nil);
// Simulate service start.
Download.ServiceStart(Download, MyDummyBoolean);
readln;
// On exit, destroy the service object.
FreeAndNil(DownloadInvoices);

缺少RestClient 文档。 什么东西被锁了? 或者如何识别锁定程序?

您的问题出在 RTL 中的 Synchronize 调用。

Synchronize 在应用程序空闲时(即没有要处理的事件)在主消息循环中获取。

正如您所说,这是一个控制台应用程序,我怀疑您没有主消息循环来注册该应用程序处于空闲状态,或处理等待中的 Synchronize 调用。

如果您想使用调用 Syncronize 的组件,则没有办法解决这个问题 - 您必须有一个适当的消息循环。最简单的方法是实现一个简单的 VCL、FMX 或服务应用程序,Synchronize 次调用将会成功。

作为替代方案,您可以编写自己的主循环。根据下面 Remy Lebeau 的评论,您需要定期调用 CheckSynchronize(),并且您可以使用 RTL 的 SyncEvent 来知道何时调用 CheckSynchronize()。该文档还提到使用全局变量 WakeMainThread 来存储一个对象方法 (TNotifyEvent),该方法在工作线程获得主线程上的锁时调用。

出于某种原因,编辑不允许我添加链接。 对于 CheckSynchronize,请参阅:https://docwiki.embarcadero.com/Libraries/en/System.Classes.CheckSynchronize

SyncEvent 参见:https://docwiki.embarcadero.com/Libraries/en/System.Classes.SyncEvent