TThread.CreateAnonymousthread / FreeOnTerminate 但随后使用 TTask / ITask
TThread.CreateAnonymousthread / FreeOnTerminate but then with TTask / ITask
背景
使用 TThread.CreateANonymousThread(aProc:TProc)
我可以创建一个线程,在线程终止后销毁线程对象。 (或者通过将线程对象的 FreeOnTerminate
设置为 true
)。这使得线程发起程序例程完成并超出范围,而线程保持 运行。 (这就是我要找的)
procedure StartProcess
begin
var lTask:=TThread.CreateAnonymousThread(
procedure
begin
... Do lengthy thread stuff here
end
);
...
lTask.Start;
end;
问题出现了 TTask.Create returns 一个 ITask
接口,当线程启动器代码删除它的上下文时(RefCount
下降到 0
-> Destroy
被调用),导致线程生成 AV。
procedure StartProcess
begin
var lTask:=TTask.Create(
procedure
begin
... Do lengthy thread stuff here
end
);
...
lTask.Start;
end; /// past this point, the subthread wil crash because the underlying task object is destroyed
在 OmniThread
的情况下,我们有一个名为 IOmniTaskCOntrol.Unobserved
的解决方案,可以避免任务对象在完成之前被销毁。
为什么?
编辑:我喜欢 ITask
接口优于 TThread
class,因为它允许松耦合和代码注入。 (prev: 因为 TThread 可能会被弃用: 忘了吧)
问题
我想知道是否(以及如何!)使用 TTask.Create(aProc:TProc)
和 ITask
界面可以完成相同的任务。到目前为止,分析源代码对我没有帮助。
答案很简单:您不需要做任何特别的事情。 TTask.Create
调用返回的 ITask
接口也被 InternalExecute
方法在内部“保留”,因此底层 TTask
对象将通过引用计数销毁。如果“主”线程不持有 ITask 接口,子线程将。直到它终止。
所以使用 TTask
这种方式非常简单。
注意:在 RS10.4.2 中这有效,我怀疑使用捕获的接口变量可能会导致 10.4.1 和更早版本中出现问题,因为内联变量问题与匿名过程相结合。 (没试过)
背景
使用 TThread.CreateANonymousThread(aProc:TProc)
我可以创建一个线程,在线程终止后销毁线程对象。 (或者通过将线程对象的 FreeOnTerminate
设置为 true
)。这使得线程发起程序例程完成并超出范围,而线程保持 运行。 (这就是我要找的)
procedure StartProcess
begin
var lTask:=TThread.CreateAnonymousThread(
procedure
begin
... Do lengthy thread stuff here
end
);
...
lTask.Start;
end;
问题出现了 TTask.Create returns 一个 ITask
接口,当线程启动器代码删除它的上下文时(RefCount
下降到 0
-> Destroy
被调用),导致线程生成 AV。
procedure StartProcess
begin
var lTask:=TTask.Create(
procedure
begin
... Do lengthy thread stuff here
end
);
...
lTask.Start;
end; /// past this point, the subthread wil crash because the underlying task object is destroyed
在 OmniThread
的情况下,我们有一个名为 IOmniTaskCOntrol.Unobserved
的解决方案,可以避免任务对象在完成之前被销毁。
为什么?
编辑:我喜欢 ITask
接口优于 TThread
class,因为它允许松耦合和代码注入。 (prev: 因为 TThread 可能会被弃用: 忘了吧)
问题
我想知道是否(以及如何!)使用 TTask.Create(aProc:TProc)
和 ITask
界面可以完成相同的任务。到目前为止,分析源代码对我没有帮助。
答案很简单:您不需要做任何特别的事情。 TTask.Create
调用返回的 ITask
接口也被 InternalExecute
方法在内部“保留”,因此底层 TTask
对象将通过引用计数销毁。如果“主”线程不持有 ITask 接口,子线程将。直到它终止。
所以使用 TTask
这种方式非常简单。
注意:在 RS10.4.2 中这有效,我怀疑使用捕获的接口变量可能会导致 10.4.1 和更早版本中出现问题,因为内联变量问题与匿名过程相结合。 (没试过)