Delphi 2007 中的 AsyncCall
我基本上想要的是启动 AsyncCall并继续加载我的代码。我的接口部分消耗了大量时间(600+毫秒),我想在独立线程中加载此代码。
我尝试使用 AsyncCall
来做这样的事情:
procedure Load;
begin
...
end;
initialization
AsyncCall(@Load, []); // or LocalAsyncCall(@Load)
但是,这个 Load
过程实际上是在主线程中启动的,而不是在新创建的线程中启动的。如何强制将 Load
过程加载到 MainThread
以外的任何线程中?
我可以创建 TThread 并执行此操作,但我想强制 AsyncCall 或 LocalAsyncCall 或 AsyncCall 中的任何内容 库才能工作。
感谢您的帮助。
What I basically want is to start AsyncCall and proceed with my code loading. I have Interface section that consumes lots of time (600+ms) and I want to load this code in independent thread.
I've tried to use AsyncCall
to make something like this:
procedure Load;
begin
...
end;
initialization
AsyncCall(@Load, []); // or LocalAsyncCall(@Load)
However, this Load
procedure actually starts in Main thread and not in the new created thread. How can I force the Load
procedure to be loaded in any thread other than MainThread
?
I can create TThread
and Execute
this but I want to force AsyncCall
or LocalAsyncCall
or anything from AsyncCall
library to make to work.
Thanks for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你尝试过这样的事情吗?:
Have you tried something like this?:
问题是您的代码没有保留由
AsyncCall
函数返回的IAsyncCall
接口。因此,一旦初始化部分完成,返回的接口的引用计数就会减为零。因此,这释放了实现执行此操作的接口的对象:
关键行是对 Sync 的调用,它强制异步调用执行完成。所有这些都发生在主线程中,这解释了您报告的行为。
解决方案是,您只需将
IAsyncCall
接口存储在变量中即可使其保持活动状态。在实际代码中,您需要确保在运行依赖于
Load
的任何代码之前已完成Load
。当您的程序达到需要调用Load
的程度时,它必须在IAsyncCall
接口上调用Sync
。所以你可以这样写。
来自需要
Load
运行的其他单元的调用EnsureLoaded
。或者,也可以从MyUnit
导出的依赖于Load
运行的任何方法调用EnsureLoaded
。后一种选择具有更好的封装性。The problem is that your code is not retaining the
IAsyncCall
interface that is returned by theAsyncCall
function.Because of this, the interface that is returned has its reference count decremented to zero as soon as the initialization section completes. This therefore frees the object that implements the interface which does this:
The key line is the call to
Sync
which forces the asynchronous call to be executed to completion. All this happens in the main thread which explains the behaviour that you report.The solution is that you simply need to keep the
IAsyncCall
interface alive by storing it in a variable.In the real code you need to ensure that
Load
had completed before running any code that is reliant onLoad
. When your program reached a point where it requiredLoad
to have been called it has to callSync
on theIAsyncCall
interface.So you might write it something like this.
The call
EnsureLoaded
from other units that requiredLoad
to have run. Or, alternatively, callEnsureLoaded
from any methods exported byMyUnit
that depended onLoad
having run. The latter option has much better encapsulation.