我有一个耗时的例程,我想用Delphi XE7的新并行库并行处理。使用Delphi XE7并行库
这里是单线程版本:
procedure TTerritoryList.SetUpdating(const Value: boolean);
var
i, n: Integer;
begin
if (fUpdating <> Value) or not Value then
begin
fUpdating := Value;
for i := 0 to Count - 1 do
begin
Territory[i].Updating := Value; // <<<<<< Time consuming routine
if assigned(fOnCreateShapesProgress) then
fOnCreateShapesProgress(Self, 'Reconfiguring ' + Territory[i].Name, i/(Count - 1));
end;
end;
end;
实在没有什么复杂的事情。如果地区列表变量被更改或设置为false,则该例程在所有销售地区周围循环并重新创建地区边界(这是耗时的任务)。
因此,这里是我的尝试,使之并行:
procedure TTerritoryList.SetUpdating(const Value: boolean);
var
i, n: Integer;
begin
if (fUpdating <> Value) or not Value then
begin
fUpdating := Value;
n := Count;
i := 0;
TParallel.For(0, Count - 1,
procedure(Index: integer)
begin
Territory[Index].Updating := fUpdating; // <<<<<< Time consuming routine
TInterlocked.Increment(i);
TThread.Queue(TThread.CurrentThread,
procedure
begin
if assigned(fOnCreateShapesProgress) then
fOnCreateShapesProgress(nil, 'Reconfiguring ', i/n);
end);
end
);
end;
end;
我把它换成for循环与并行for循环。计数器'i'被锁定,因为它会增加以显示进度。然后我将OnCreateShapeProgress事件包装在一个TThread.Queue中,由主线程处理。 OnCreateShapeProgress事件由更新描述任务的进度条和标签的例程处理。
如果我排除对OnCreateShapeProgress事件的调用,则该例程有效。它与EAurgumentOutOfRange错误崩溃。
所以我的问题很简单:
我在做什么蠢事?
如何从TParallel.For循环或TTask中调用事件处理程序?
'TParallel.For'在XE7中有一个错误,在更新1中已修复。我认为它在这里没有任何意义,但是仍然使用更新进行测试。请参阅[TParallel.For保留区,但不能释放内存](https://quality.embarcadero.com/browse/RSP-9564)。 – 2014-11-14 22:57:31