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

Ответы на вопрос(1)

Ваш ответ на вопрос