Использование параллельной библиотеки 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?