Проблема многопоточности Ghostscript.NET
Самая длинная часть ежемесячного процесса, который мы запускаем, - это автоматическая нарезка и преобразование некоторых PDF-файлов в изображения. Каждый PDF-файл считывается, преобразуется в 3 различных PDF-файла, а эти 3 преобразуются в изображения, которые можно отправить клиентам по электронной почте. PDF-файлы уникальны для каждого клиента, и мы отправляем ежемесячный PDF-документ как минимум 15 000 (часто более 22 000) клиентов.
Наше создание PDF и нарезка уже многопоточны, но я старался распараллелить оставшиеся части этого.
С этой целью я преобразовал наш процесс для использования Ghostscript.NET, который якобы является библиотекой, поддерживающей распараллеливание Ghostscript.
Для этого я обернул этот код в цикл Parallel.Foreach(), где каждая итерация цикла работает с различным исходным PDF:
GhostscriptVersionInfo gsVersionInfo = GhostscriptVersionInfo.GetLastInstalledVersion(GhostscriptLicense.GPL | GhostscriptLicense.AFPL, GhostscriptLicense.GPL); GhostscriptProcessor processor = null; try { //sArgs is an array of arguments for ghostscript processor = new GhostscriptProcessor(gsVersionInfo, true); processor.StartProcessing(sArgs, new ConsoleStdIO(true,false,true)); while (processor.IsRunning) { Thread.Sleep(100); } }
Когда я запускаю приведенный выше код и заставляю Parallel.Foreach использовать только 1 поток (отключение распараллеливания), он работает так же, как и раньше, и правильно генерирует все файлы. Если я использую 5 степеней распараллеливания, он начинает выбрасывать ошибки. Эти ошибки различаются, но, как правило, указывают на неправильно сформированные входные PDF-файлы, из-за чего я думаю, что процессоры ghostscript на самом деле не являются поточно-ориентированными и работают на входах друг друга.
Как правильно использовать Ghostscript.NET для одновременного запуска нескольких экземпляров ghostscript в разных файлах?
1 ответ
Я использую Ghostscript.NET с многопоточностью. Код, которым вы поделились выше, должен быть внутри цикла Parallel.For. да весь код, который означает, начиная с
GhostscriptVersionInfo gsVersionInfo = GhostscriptVersionInfo.GetLastInstalledVersion(GhostscriptLicense.GPL | GhostscriptLicense.AFPL, GhostscriptLicense.GPL);
до конца и все должно работать. Как упоминалось выше @KenS, каждый многопоточный процесс должен использовать свой экземпляр GhostscriptProcessor
,