- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一组任务来执行它们在一个数组中。我想遍历数组并为每个数组启动一个任务。
下面的例子很简单(计算平方)来说明这个问题。
program FutureSquares;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Threading,
System.Classes;
const
nums: array[0..9] of Integer = (1,2,3,4,5,6,7,8,9,10);
var
i, contextIndex: Integer;
f: array[0..9] of ITask;
answer, futureAnswer: Integer;
matchDisplay: string;
futureFunc: TFunc<Integer>;
begin
try
for i := Low(f) to High(f) do
begin
contextIndex := i;
futureFunc := function: Integer
begin
Sleep(Random(1000));
Result := nums[contextIndex]*nums[contextIndex]; // trying because a reference to it is captured. How to capture the actual value?
end;
f[i] := TTask.Future<Integer>(futureFunc);
f[i].Start;
end;
//verify results in sequential manner
for i := Low(f) to High(f) do
begin
answer := nums[i]*nums[i];
futureAnswer := IFuture<Integer>(f[i]).Value;
if futureAnswer = answer then
matchDisplay := 'match'
else
matchDisplay := 'MISMATCH';
writeln(Format('%d * %d = %d. Future<Integer> = %d - %s', [nums[i],nums[i],answer, futureAnswer, matchDisplay]));
end;
readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
1 * 1 = 1. Future<Integer> = 16 - MISMATCH
2 * 2 = 4. Future<Integer> = 100 - MISMATCH
3 * 3 = 9. Future<Integer> = 100 - MISMATCH
4 * 4 = 16. Future<Integer> = 100 - MISMATCH
5 * 5 = 25. Future<Integer> = 100 - MISMATCH
6 * 6 = 36. Future<Integer> = 100 - MISMATCH
7 * 7 = 49. Future<Integer> = 100 - MISMATCH
8 * 8 = 64. Future<Integer> = 100 - MISMATCH
9 * 9 = 81. Future<Integer> = 100 - MISMATCH
10 * 10 = 100. Future<Integer> = 100 - match
最佳答案
您需要捕获值而不是匿名方法中的变量。最简单的方法是将匿名方法放在独立函数中,并传递您要捕获的索引。这样,将捕获值而不是变量。
function CaptureFuture(const aTheIndex: Integer): TFunc<Integer>;
begin
Result := function: Integer
begin
Sleep(Random(1000));
Result := nums[aTheIndex]*nums[aTheIndex]; // trying because a reference to it is captured. How to capture the actual value?
end;
end;
for i := Low(f) to High(f) do
begin
futureFunc := CaptureFuture(i);
f[i] := TTask.Future<Integer>(futureFunc);
f[i].Start;
end;
1 * 1 = 1. Future<Integer> = 1 - match
2 * 2 = 4. Future<Integer> = 4 - match
3 * 3 = 9. Future<Integer> = 9 - match
4 * 4 = 16. Future<Integer> = 16 - match
5 * 5 = 25. Future<Integer> = 25 - match
6 * 6 = 36. Future<Integer> = 36 - match
7 * 7 = 49. Future<Integer> = 49 - match
8 * 8 = 64. Future<Integer> = 64 - match
9 * 9 = 81. Future<Integer> = 81 - match
10 * 10 = 100. Future<Integer> = 100 - match
关于delphi - 如何在Delphi中将循环内的上下文传递到TTask.IFuture?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47706948/
单击按钮后,我创建 3 个任务,每个任务都有空过程,并将方法调用和任务列表完成的时间差写入控制台: procedure TWinTest.BtnThreadTestClick(Sender: TObj
根据我阅读 Nick Hodges 的理解,这段代码应该没问题: TTask.Run( procedure var resp, tmp: string; req: boolea
专家,请看下面的代码片段: var aAllTasks : Array [0..1] of ITask //global private var Procedure SetImage(); be
我不知道如何在 Delphi 中正确使用 TTask。 我创建了一个 TTask。 syncTask := ttask.Create(SyncMysqlDatabase); 以下代码在onlocati
我对线程的经验有限。我想并行读取一些基本的数据库表,我需要等到所有表都读取完,程序才能合理地进行。在这方面,阻塞主线程对我来说没问题。 此代码(简化版)工作正常: procedure ReadDBMu
我有以下两种多线程代码方法来完成相同的工作。 任务: const MaxThreadCount = 80; procedure TWorkerTask.Update; var aTasks
Delphi 中的匿名方法创建一个闭包,该闭包在上下文中保持“包围”局部变量,直到匿名方法完成。如果使用接口(interface)变量,那么它们将在匿名方法完成之前减少其引用的实例。到目前为止一切顺利
背景 使用 TThread.CreateANonymousThread(aProc:TProc)我可以创建一个线程,在线程终止后销毁线程对象。 (或者将 FreeOnTerminate 设置为 tru
这是我在 DLL 中的代码: procedure TTaskTest; begin TTask.Run( procedure begin Sleep(300);
我是一名优秀的程序员,十分优秀!