我有一个运行长操作的模型对象。我尝试在线程中运行其中一些操作以保持接口响应,一次下载2件事等,但我想尽可能地从接口代码中隐藏这些细节。我试图使用AsyncCall库,但遇到问题。
type EUpdaterAction = (auFoundCurrentVersion, auFoundUpdateVersion);
type
TUpdater = class
public
procedure loadCurrentVersion();
procedure notify(action: EUpdaterAction);
end;
procedure TUpdater.loadCurrentVersion();
begin
TAsyncCalls.Invoke(procedure
begin
Assert(Windows.GetCurrentThreadId() <> System.MainThreadID);
//Really long code
TAsyncCalls.VCLSync(procedure begin notify(auFoundCurrentVersion); end);
end);
end;
断言失败。我是否需要做一些事情才能让它在一个单独的线程中运行,或者第一个example shown with the library是否实际上没有在线程中运行?
答案 0 :(得分:6)
您需要调用IAsyncCall.ForceDifferentThread
来强制代码在不同的线程中运行。在您的示例中,TAsyncCalls.Invoke()返回的接口会立即释放,因为该函数结束并且释放IAsyncCall接口会调用Sync
方法。并且由于您的任务尚未开始,Sync
方法将在同一个线程中执行它,除非调用了ForceDifferentThread
方法。
TAsyncCalls.Invoke(procedure
begin
Assert(Windows.GetCurrentThreadId() <> System.MainThreadID);
//Really long code
TAsyncCalls.VCLSync(procedure begin notify(auFoundCurrentVersion); end);
end).ForceDifferentThread; // <<<<<
但这真的是你想要的吗?我想你想在loadCurrentVersion()退出后保持线程活着。而对于这个AsyncCalls不是正确的工具。
答案 1 :(得分:1)
已经在SO上讨论过了。当您调用Invoke
时,AsyncCalls会将您的代码放入要执行的队列中;稍后Asyncalls将找到一个工作线程来执行您的代码,但如果您的代码在之前调用Sync
,则会将一个工作线程分配给您的代码(并且不使用ForceDifferentThread
)AsyncCalls从队列中删除您的代码并在主线程中执行它。这是设计的。