Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

### Ошибка EAurgumentOutOfRange при работе с параллельными циклами в Delphi XE7

Delphi , Компоненты и Классы , Потоки

Ошибка EAurgumentOutOfRange при работе с параллельными циклами в Delphi XE7

Вопрос пользователя связан с ошибкой EAurgumentOutOfRange, возникающей при попытке использования нового параллельного API в Delphi XE7 для выполнения ресурсоемкой операции. В примере кода, представленном пользователем, используется цикл TParallel.For для распараллеливания обработки данных. Однако, при попытке вызова обработчика события fOnCreateShapesProgress из этого цикла, возникает указанная ошибка.

Пример кода:

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 := Value; // ресурсоемкая операция
        TInterlocked.Increment(i);
        TThread.Queue(TThread.CurrentThread,
          procedure
          begin
            if assigned(fOnCreateShapesProgress) then
              fOnCreateShapesProgress(nil, 'Reconfiguring ' + Territory[Index].Name, i / n);
          end);
      end);
  end;
end;

Проблема:

При использовании TThread.Queue в параллельном цикле TParallel.For возникает ошибка EAurgumentOutOfRange, если в коде присутствует вызов обработчика события.

Решение:

Из комментариев к вопросу пользователя становится ясно, что проблема кроется в использовании TThread.Queue с параметром TThread.CurrentThread. Это некорректно, так как TThread.CurrentThread - это именно тот поток, из которого выполняется вызов TThread.Queue, и ожидается, что будет использован другой поток, например, главный поток приложения.

Чтобы решить проблему, следует использовать однопараметрический вариант TThread.Queue, который не принимает параметр потока, а также переместить инкремент счетчика прогресса в главный поток, чтобы избежать гонки данных:

procedure TTerritoryList.SetUpdating(const Value: boolean);
var
  i, n: Integer;
begin
  if (fUpdating <> Value) or not Value then
  begin
    fUpdating := Value;

    n := Count;

    TParallel.For(0, Count - 1,
      procedure(Index: Integer)
      begin
        Territory[Index].Updating := Value; // ресурсоемкая операция
        TThread.Queue(
          procedure
          begin
            TInterlocked.Increment(i); // инкремент счетчика в главном потоке
            if assigned(fOnCreateShapesProgress) then
              fOnCreateShapesProgress(nil, 'Reconfiguring ' + Territory[Index].Name, i / n);
          end);
      end);
  end;
end;

Также важно отметить, что в последних версиях Delphi для атомарного инкремента следует использовать метод AtomicIncrement.

Дополнительные замечания:

  • Перед использованием параллельных циклов рекомендуется обновить свой проект до последнего обновления Delphi XE7, так как в нем исправлены некоторые ошибки, связанные с параллельным API.
  • Использование TThread.Synchronize вместо TThread.Queue также может быть решением для выполнения кода в главном потоке, но важно убедиться, что это необходимо, так как TThread.Synchronize блокирует выполнение до завершения выполнения переданной ему процедуры.

Следуя этим рекомендациям, можно избежать ошибки EAurgumentOutOfRange и успешно использовать параллельные циклы в Delphi XE7 для улучшения производительности ресурсоемких операций.

Создано по материалам из источника по ссылке.

Вопрос пользователя касается исправления ошибки EAurgumentOutOfRange, связанной с неправильным использованием TThread.Queue в контексте параллельного программирования в Delphi XE7.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Потоки ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2024-12-26 14:11:21/0.003303050994873/0