Delphi中的匿名方法创建了一个闭包,它将"周围"的局部变量保存在上下文中,直到匿名方法完成.如果使用接口变量,那么它们将在匿名方法完成之前减少其引用的实例.到现在为止还挺好.
当使用带有匿名方法的TTask.Run(AProc:TProc)时,我希望在关联的工作线程完成执行"AProc"时释放闭包.但这似乎没有发生.在程序终止时,当线程池(此TTask生成的线程所属的)被释放时,您终于可以看到这些本地引用的实例被释放 - 即闭包显然已被释放.
问题是这是一个功能还是一个bug?或者我在这里监督一些事情?
下面,在TTask.Run(...)之后.等待我希望调用LFoo的析构函数 - 这不会发生.
procedure Test3;
var
LFoo: IFoo;
begin
LFoo := TFoo.Create;
TTask.Run(
procedure
begin
Something(LFoo);
end).Wait; // Wait for task to finish
//After TTask.Run has finished, it should let go LFoo out of scope - which it does not apprently.
end;
Run Code Online (Sandbox Code Playgroud)
以下是一个完整的测试用例,它表明一个"简单"的匿名方法按预期工作(Test2),但是当输入TTask.Run时它没有(Test3)
program InterfaceBug;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Classes,
System.SysUtils,
System.Threading;
type
//Simple Interface/Class
IFoo = interface(IInterface)
['{7B78D718-4BA1-44F2-86CB-DDD05EF2FC56}']
procedure Bar;
end;
TFoo = class(TInterfacedObject, IFoo)
public
constructor Create;
destructor Destroy; override;
procedure Bar; …Run Code Online (Sandbox Code Playgroud)