Распараллелить цикл

Автор Тема: Распараллелить цикл  (Прочитано 3412 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 809
  • Карма: 166
    • Мои плагины к Автокаду
Распараллелить цикл
« : 15-12-2018, 19:26:08 »
Хочу попробовать использовать Parallel.ForEach (или что там есть еще в C#) в надежде, что удастся задействовать более одного ядра процессора. Но можно ли распаралеливать код плагинов Автокада? Вроде как нельзя, да? (https://www.keanw.com/2013/04/querying-autocad-objects-of-a-particular-type-using-net.html)
Но я минимизировал вызовы API внутри цикла, обращаюсь только к простым структурам Point2d, Extents2d и т.п. Может заработать?
А если создавать и диспозить DisposableWrapper в пределах одного потока?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Распараллелить цикл
« Ответ #1 : 15-12-2018, 20:40:10 »
avc,
Я бы не советовал. Только то, что не работает с AutoCAD API можешь распараллеливать (если оно это допускает). Где боком вылезет распараллеливание обращений к классам/методам AutoCAD думаю не известно даже его авторам.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Re: Распараллелить цикл
« Ответ #2 : 16-12-2018, 00:33:50 »
Я выделял текущий поток, на который направлял работу с API автокада, а всевозможные расчеты и пр - паралеллились и обращались к последнему (по аналогии по обращению к GUI что WF, что WPF).

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 809
  • Карма: 166
    • Мои плагины к Автокаду
Re: Распараллелить цикл
« Ответ #3 : 16-12-2018, 01:03:40 »
Я выделял текущий поток, на который направлял работу с API автокада, а всевозможные расчеты и пр - паралеллились и обращались к последнему (по аналогии по обращению к GUI что WF, что WPF).
Это как? Можно примерчик?
Я рискнул, попробовал. Ничего из API толком не вызываю, кроме конструкторов простейших структур . Автокад вышибает мгновенно :( Никакого даже сообщения. Просто молча завершает работу :(

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Re: Распараллелить цикл
« Ответ #4 : 17-12-2018, 23:59:40 »
Не обещаю, что напишу до выходных (что-то заработался совсем), может кто раньше покажет, пока можешь написать, что упрощенно надо показать (пример, что надо сделать).

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: Распараллелить цикл
« Ответ #5 : 18-12-2018, 10:03:07 »
Это как? Можно примерчик?
Это использование Task и async / await. Примеров в интернете полно. Страшная штука - до сих пор мучаюсь с этим)) Вроде использую часто, но без гугла не обходится ))
Использование зависит от конкретной задачи и я сомневаюсь, что вообще такие задачи встречаются.
Еще можно использовать Thread'ы, но это как-бы уже не тру, ибо считается устаревшим

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 809
  • Карма: 166
    • Мои плагины к Автокаду
Re: Распараллелить цикл
« Ответ #6 : 18-12-2018, 11:33:53 »
Например, пытаюсь сделать расчеты над элементами коллекции параллельно. Обращаюсь к структурам типа Point2d - проблем нет. Результаты складываю в  ConcurrentBag. Все прекрасно работает. НО хочу добавить индикатор прогресса и возможность прервать процесс по Esc. Использую LongOperationManager как учил великий Ленин Киан. Оно тоже прекрасно работало, пока не распараллелил.
Код - C# [Выбрать]
  1.           ConcurrentBag<PSegmentColl> inL = new ConcurrentBag<PSegmentColl>();
  2.           ConcurrentBag<PSegmentColl> outL = new ConcurrentBag<PSegmentColl>();
  3.           ConcurrentBag<PSegment> free = new ConcurrentBag<PSegment>();
  4.  
  5.           using (LongOperationManager lom = new LongOperationManager("Идет обработка", knots.Count)) // Индикатор прогресса (обертка для MeterProgress) https://www.keanw.com/2007/08/a-handy-net-cla.html
  6.           {
  7.             Parallel.ForEach(knots, col => Working2d(col, tol, ref inL, ref outL, ref free, ref loopCount));
  8.             // не важно что там внутри Working2d - оно работает, раскидывает элементы списка по другим спискам как мне надо
  9.           }
Есть ли способ обратиться к lom.Tick(), так чтоб Автокад не вышибло?

await - это вообще выше моего понимания. Ниасилил :) А вот заменить foreach на параллельный - это выглядит очень соблазнительно. Как увидел такую фичу - сразу загорелся.

Оффлайн RevitTormentor

  • ADN OPEN
  • ***
  • Сообщений: 162
  • Карма: 6
Re: Распараллелить цикл
« Ответ #7 : 05-04-2019, 15:28:23 »
Это как? Можно примерчик?
Это использование Task и async / await. Примеров в интернете полно. Страшная штука - до сих пор мучаюсь с этим)) Вроде использую часто, но без гугла не обходится ))
Использование зависит от конкретной задачи и я сомневаюсь, что вообще такие задачи встречаются.
Еще можно использовать Thread'ы, но это как-бы уже не тру, ибо считается устаревшим

async/await и многопоточность - это вроде как не одно и то же.
Там асинхронность, а там потоки.

Потоки устареть не могут. Они были есть и будут.