本文整理自网络,侵删。
很多时候我们会用ttask.waitforall等待一组任务的结果,然后在主线程UI里面报告运行结果, 因为waitforall方法是阻塞式的等待,如果直接在主线程里执行,会卡死UI, 所以就尝试开另一个task用来等待这组任务的结束,如下代码:
var aTask: array of ITask; i: integer;begin sfLogger.logMessage('The start.'); setlength(aTask, 10); for i := 0 to 9 do begin aTask[i] := TTask.Run( procedure var aValue: integer; begin aValue := Random(2000); sleep(aValue); tthread.Synchronize(nil, procedure begin mmo1.Lines.Add(aValue.ToString()); end); end); end; TTask.Run( procedure begin TTask.WaitForAll(aTask); tthread.Synchronize(nil, procedure begin mmo1.Lines.Add('END.'); end); end);end;
运行是很顺利, 但当关闭应用后报告有内存出错!
很明显是这组TTask资源在运行过waitforall后就没能成功释放! 但如果在主线程里面用waitforall,则完全没这个问题!
所以建议自行用计算数记录剩余任务数的方法来自行处理等待吧!
下面是示例:
var aTask: array of ITask; i, lvC: integer;begin sfLogger.logMessage('The start.'); setlength(aTask, 10); lvC := 0; for i := 0 to 9 do begin AtomicIncrement(lvC); aTask[i] := TTask.Run( procedure var aValue: integer; begin aValue := Random(2000); sleep(aValue); tthread.Synchronize(nil, procedure begin mmo1.Lines.Add(aValue.ToString()); end); AtomicDecrement(lvC); end); end; while lvC>0 do Application.ProcessMessages; mmo1.Lines.Add('END.'); {TTask.Run( procedure begin TTask.WaitForAll(aTask); tthread.Synchronize(nil, procedure begin mmo1.Lines.Add('END.'); end); end);}end;
=======================
而具戏剧性的是,如果, 这个waitforall也不是一定不能放在task里面等待, 如果将aTask[i]:=TTask.run(...)这个变成通过一个procedure来赋值就没事:
procedure runtask(var aTask: ITask);begin aTask := TTask.Run( procedure var aValue: integer; begin aValue := Random(2000); sleep(aValue); sfLogger.logMessage(aValue.ToString()); end);end; procedure TForm1.Button4Click(Sender: TObject);var aTask: array of ITask; i: integer;begin sfLogger.logMessage('The start.'); setlength(aTask, 10); for i := 0 to 9 do begin // Sleep(1); runtask(aTask[i]); end; TTask.Run( procedure begin TTask.WaitForAll(aTask); tthread.Synchronize(nil, procedure begin mmo1.Lines.Add('END.'); end); end);end;
而runtask可以是procedure也可以是function, 但一定不能是嵌套函数,否则也会内存泄露.
这算不算XE7的大坑??!!不知道10.2有没有修复此问题.――――――――――――――――
原文链接:https://blog.csdn.net/rocklee/article/details/72953953
相关阅读 >>
Delphi的unicode与gb2312转转换,汉字unicode转gb2312
更多相关阅读请进入《Delphi》频道 >>