Фон
Используя TThread.CreateANonymousThread(aProc:TProc)
, я могу создать поток, который уничтожает объект потока после завершения потока. (или, альтернативно, установив FreeOnTerminate
в true
для объекта thread). Это позволяет процедуре инициатора потока завершиться и выйти за пределы области действия, в то время как поток продолжает работать. (Это то, что я ищу)
procedure StartProcess
begin
var lTask:=TThread.CreateAnonymousThread(
procedure
begin
... Do lengthy thread stuff here
end
);
...
lTask.Start;
end;
Проблема возникает из-за того, что TTask.Create возвращает интерфейс 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
, потому что он допускает слабую связь и внедрение кода. (предыдущая: Поскольку TThread может быть устаревшим: просто забудьте об этом)
Вопрос
Мне было интересно, можно ли (и как!) с помощью TTask.Create(aProc:TProc)
и интерфейса ITask
добиться того же самого. Анализ исходного кода мне пока не помог.
TThread
не устаревает. - person Andreas Rejbrand   schedule 01.03.2021