Я пытаюсь создать несколько PDF-файлов параллельно, используя функцию IronPDF HTML в PDF. Но при запуске из ASP.NET он блокируется :(
Я воссоздал проблему здесь: https://github.com/snebjorn/ironpdf-threading-issue-aspnet
Вот фрагмент с основными частями.
Звонок GetSequential()
работает. Но не выполняется параллельно.
GetSimple()
работает параллельно, но взаимоблокируется.
public class TestController : Controller
{
[HttpGet]
[Route("simple")]
public async Task<IActionResult> GetSimple()
{
var tasks = Enumerable
.Range(1, 10)
.Select(i => HtmlToDocumentAsync("hello", i));
var pdfs = await Task.WhenAll(tasks);
using var pdf = PdfDocument.Merge(pdfs);
pdf.SaveAs("output.pdf");
return Ok();
}
[HttpGet]
[Route("seq")]
public async Task<IActionResult> GetSequential()
{
var pdfs = new List<PdfDocument>();
foreach (var i in Enumerable.Range(1, 10))
{
pdfs.Add(await HtmlToDocumentAsync("hello", i));
}
using var pdf = PdfDocument.Merge(pdfs);
pdf.SaveAs("output.pdf");
return Ok();
}
private async Task<PdfDocument> HtmlToDocumentAsync(string html, int i)
{
using var renderer = new HtmlToPdf();
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf;
}
}
Согласно https://medium.com/rubrikkgroup/understanding-async-avoiding-deadlocks-e41f8f2c6f5d это потому, что поток, выполняющий метод контроллера, не является основным потоком. Таким образом, он просто добавляется в пул потоков, и в какой-то момент мы ждем продолжения потока контроллера, но он не возвращается в расписание. Это происходит, когда мы смешиваем async/await
с .Wait/.Result
.
Итак, прав ли я, предполагая, что внутри пакета .Wait/.Result
происходят IronPDF.Threading
вызовы?
Есть ли обходной путь?
ОБНОВЛЯТЬ:
Я обновился до IronPdf 2021.9.3737, и теперь он работает 🎉
Также обновлено https://github.com/snebjorn/ironpdf-threading-issue-aspnet
К сожалению нет. Я связывался с IronPdf, и они пытались исправить это в IronPdf.Threading, но это ломает другие вещи. Они работают над обновлением движка рендеринга, который должен исправить/улучшить многопоточность, который, как мне сказали, должен быть выпущен в марте 2021 года. Я пробовал v2021.3.1, и он все еще не работает. Так что все еще ждем.
Я не понимаю пакет IronPdf.Threading. Пространство имен не включает никаких классов или расширений... и никаких документов. Но я думаю, что тогда мне придется ждать обновления. Очень медленно конвертирует 1000 pdf за раз.
Спасибо, что нашли время сообщить об исправлении и задокументировать его, Snæbjørn. Супер полезно знать.
Вот как нужно делать вопросы в стеке. Отличное объяснение, отличная демонстрация на github, и ваше решение сработало для меня. После обновления версии это было исправлено. У меня были проблемы с этим в течение недели.
Поддержка Iron Software здесь.
Наши инженеры протестировали ваш образец проекта, увеличив число итераций до 150, и убедились, что он работает без проблем.
Мы ожидаем, что ваш вариант использования заключается в том, что вы создаете несколько потоков для создания файлов PDF и сохраняете эти файлы в массиве для последующего объединения?
Предполагая, что это так, вероятной причиной этой проблемы является отправка слишком большого массива в метод слияния, для обработки которого требуется большой объем оперативной памяти. Сбой — это память, не обрабатывающая большое количество PDF-файлов для слияния.
Подготовка сервера: если я попытаюсь открыть 150 вкладок в Chrome на перегруженном настольном ПК, я ожидаю, что он выйдет из строя или зависнет. Если я автоматизирую открытие 150 "вкладок" браузера на гораздо менее мощном сервере... я ожидаю мгновенных, стабильных результатов??
@darren Я обновил свой пример проекта до IronPdf 2021.9.3737 и могу подтвердить, что теперь он работает :)
привет, @даррен! кажется, я застрял с той же проблемой тупика на MacOS с M1. Среда выполнения x64, dotnet6, версия 2022.9.9049. (работает на окнах)
MacOs плохо работает с CEF, который требует, чтобы исходный поток пользовательского интерфейса никогда не уничтожался/изменялся. Это требование не существует в Windows или Linux. ASP.NET иногда переключается на другой поток, когда делается новый запрос, и в результате этот запрос зависает, поскольку Chrome не может обработать работу. Обходной путь заключается в том, чтобы по существу создать постоянный поток для Chrome и выполнить работу HTML-to-PDF в этом потоке. См. github.com/Waytal/IronPDFIssue/pulls?q=is%3Apr+is%3Aclosed
Просто хотел добавить к этому, что поддержка многопоточности IronPdf в веб-приложениях MVC отсутствует. Вы столкнетесь с бессрочными взаимоблокировками, если вы выполняете рендеринг в контексте HTTP-запроса. Мы были взволнованы обещанием обновить средство визуализации, которое решит проблему (которое, как нам сказали, должно быть выпущено в июне/июле 2021 года), но, похоже, оно было отложено. Я протестировал обновленный рендерер, используя их «пакет раннего доступа», и взаимоблокировка была заменена 10-секундными блоками потоков и, по-видимому, случайными исключениями C++, так что это далеко не исправлено. Производительность выше в однопоточном режиме.
Ответ Даррена неверен — я бесчисленное количество раз проходил через наши вызовы рендеринга, пытаясь исправить это, и взаимоблокировка возникает при вызове HtmlToPdf.StaticRenderHtmlAsPdf
, а не при вызове PdfDocument.Merge
. Это проблема с потоками.
Я предлагаю избегать IronPdf, если вы еще не купили их продукт. Найдите другое решение.
Сегодня я использовал IronPDF в ветке 2021.9.3737 без каких-либо проблем с потоками в Windows и Linux благодаря помощи Даррена в другой ветке.
Я согласен с abagonhishead в том, что StaticRenderHtmlAsPdf использовался для создания очереди PDF-документов для рендеринга, а на недостаточно подготовленном сервере это заканчивалось тупиком потока... очередь становилась все длиннее и длиннее, поскольку сервер изо всех сил пытался отображать PDF-файлы.
Решение, которое сработало для меня:
Мне удалось заблокировать IronPdf.EAP v2021.5.1.1. Я не пробовал последнюю версию v2021.6.3, надеюсь, это исправлено. Хорошая заметка о недостаточно подготовленном сервере. Я запускаю свои тесты на таком сервере.
Полностью Снебьёрн. Преобразование веб-страницы в PDF-файл требует мощности рычага рабочего стола. Пришлось посмотреть на мой сервер сек. Если бы я не запускал хром на сервере весь день ... почему я должен ожидать, что Html to PDF будет работать (facepalm ironpdf.com/docs/questions/azure)
Я обновился до IronPdf 2021.9.3737, и, похоже, проблема с взаимоблокировкой устранена.
как вы можете видеть из прикрепленного изображения, я протестировал ваш код с 1000 итерациями, и он работает без проблем, я полагаю, что проблема может возникнуть, когда вы увеличиваете итерации или вводите большой размер HTML, который достигает максимального объема ЦП и памяти, который не может ручка. Кроме того, я не согласен с abagonhishead, потому что на рынке нет альтернативного решения, которое предлагает все эти функции.
Вы нашли решение этой проблемы? У меня та же проблема! :-(