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
使用 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