用Delphi 2007 AsyncCall [英] AsyncCall with Delphi 2007

查看:118
本文介绍了用Delphi 2007 AsyncCall的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想基本上是启动<一个href=\"http://andy.jgknet.de/blog/bugfix-units/asynccalls-29-asynchronous-function-calls/\">AsyncCall和我的code加载进行。我有一个消耗大量的时间(600 + ms)的接口部分,我想在独立的线程加载该code。

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.

我试图用 AsyncCall 来让这样的事情:

I've tried to use AsyncCall to make something like this:

procedure Load;
begin
...
end;

initialization
  AsyncCall(@Load, []); // or LocalAsyncCall(@Load)

然而,这加载程序真正开始在主线程,而不是在新创建的线程。我怎样才能迫使加载程序比 MainThread

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?

我可以创建的TThread 执行这一点,但我想强制 AsyncCall LocalAsyncCall 或任何东西从 AsyncCall 库进行工作。

I can create TThread and Execute this but I want to force AsyncCall or LocalAsyncCall or anything from AsyncCall library to make to work.

感谢您的帮助。

推荐答案

的问题是,你的code未保留了由返回 IAsyncCall 接口 AsyncCall 功能。

The problem is that your code is not retaining the IAsyncCall interface that is returned by the AsyncCall function.

AsyncCall(@Load, []);
//AsyncCall returns an IAsyncCall interface,
//but this code does not take a reference to it

由于这个原因,则返回该接口有其引用计数尽快初始化部分完成递减到零。因此,这将释放实现其做此接口的对象:

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:

destructor TAsyncCall.Destroy;
begin
  if FCall <> nil then
  begin
    try
-->   FCall.Sync; // throw raised exceptions here
    finally
      FCall.Free;
    end;
  end;
  inherited Destroy;
end;

关键行是调用同步它会强制执行到结束异步调用。所有这一切都发生在主线程这也解释了你报道的行为。

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.

解决的办法是,你只需要保持 IAsyncCall 接口活活将其存储在一个变量。

The solution is that you simply need to keep the IAsyncCall interface alive by storing it in a variable.

var
  a: IAsyncCall;

initialization
  a := AsyncCall(@Load, []);

在实际code,你需要确保加载运行任何code,它是依赖于加载之前已经完成了。当你的程序的地步了需要它加载来一直呼吁它调用同步 IAsyncCall 接口。

In the real code you need to ensure that Load had completed before running any code that is reliant on Load. When your program reached a point where it required Load to have been called it has to call Sync on the IAsyncCall interface.

所以,你可能会写这样的事情。

So you might write it something like this.

unit MyUnit;

interface

procedure EnsureLoaded;

implementation

uses
  AsyncCalls;

....

procedure Load;
begin
  ....
end;

var
  LoadAsyncCall: IAsyncCall;

procedure EnsureLoaded;
begin
  LoadAsyncCall := nil;//this will effect a call to Sync
end;

initialization
  LoadAsyncCall := AsyncCall(@Load, []);

end.

从其他单位,需要加载来运行了呼叫 EnsureLoaded 。或者,调用 EnsureLoaded MyUnit 导出任何方法是依赖于加载有运行。后一种选择具有更好的封装。

The call EnsureLoaded from other units that required Load to have run. Or, alternatively, call EnsureLoaded from any methods exported by MyUnit that depended on Load having run. The latter option has much better encapsulation.

这篇关于用Delphi 2007 AsyncCall的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆