Multithreading – asynccall and Delphi 2007

What I basically want is to start asynccall and continue my code loading I have an interface part that consumes a lot of time (600 ms) and I want to load this code in a separate thread

I tried to use asynccall to do something like this:

procedure Load;
begin
...
end;

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

However, this load process is actually started in the main thread, not in the newly created thread How do I force the load process to load into any thread other than mainthread?

I can create a TThread and execute this, but I want to force asynccall or localasynccall or any work from the asynccall library

Thanks for your help.

Solution

The problem is that your code does not retain the iasynccall interface returned by the asynccall function

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

Therefore, once the initialization part is completed, the reference count of the returned interface is decremented to zero This frees the object that implements the interface to do so:

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 is to call sync to force the asynchronous call to be completed All this happens in the main thread, which explains the behavior you report

The solution is that you only need to store the iasynccall interface in a variable

var
  a: IAsyncCall;

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

In real code, you need to ensure that load is complete before running any load - dependent code When your program reaches the required loading location, you must call sync on the iasynccall interface

So you might write 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.

Invoke ensureloaded. From other units that need to be loaded and run Or, any method exported by myunit that depends on the run load calls ensureloaded The latter option has better encapsulation

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>