5

I'm trying to generate multiple PDFs in parallel using IronPDFs HTML to PDF feature. But it appears to be deadlocking when started from ASP.NET :(

I've recreated the problem here: https://github.com/snebjorn/ironpdf-threading-issue-aspnet

Here's a snippet with the essential parts.

Calling GetSequential() works. But is not executing in parallel. GetSimple() is running in parallel but deadlocks.

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;
    }
}

According to https://medium.com/rubrikkgroup/understanding-async-avoiding-deadlocks-e41f8f2c6f5d it's because the thread executing the controller method isn't a main thread. So it just gets added to the thread pool and at some point we're waiting for the controller thread to continue but it's not getting scheduled back in. This happens when we mix async/await with .Wait/.Result.

So am I right to assume that there are .Wait/.Result calls happening inside the IronPDF.Threading package?

Is there a workaround?


UPDATE:

I updated to IronPdf 2021.9.3737 and it now appears to work

Also updated https://github.com/snebjorn/ironpdf-threading-issue-aspnet

Snæbjørn
  • 10,322
  • 14
  • 65
  • 124
  • Did you find a solution to this? I got the same problem! :-( – Casper TL Mar 26 '21 at 14:58
  • Unfortunately no. I've been in contact with IronPdf and they've tried to fix it in IronPdf.Threading but that breaks other stuff. They're working on a render engine revamp that should fix/improve threading, which I'm told should release March 2021. I tried v2021.3.1 and that's still not working. So still waiting. – Snæbjørn Mar 30 '21 at 16:33
  • I don't understand the IronPdf.Threading package. The namespace does not include any classes or extensions... and no docs. But I guess I'll have to wait for an update then. It's very slow converting 1000 pdfs at a time. – Casper TL Mar 31 '21 at 18:19
  • Thanks for taking the time to report the fix works and document it Snæbjørn. Super helpful to know. – Stephanie Oct 06 '21 at 03:01
  • This is how one should do questions on stack. Great explanation, great demo on github and your solution worked for me. After upgrading the version it was fixed. I was having issues with this over a week. – G.Dimov Feb 21 '22 at 08:59

4 Answers4

5

Just wanted to add to this that IronPdf's multi-threading support on MVC web apps is non-existent. You will end up with indefinite deadlocks if you're rendering in the context of an HTTP request. We have been strung along with the promise of an updated renderer that would resolve the issue (which we were told should be released June/July 2021) but that appears to have been pushed back. I tested the updated renderer using their 'early-access package' and the deadlocking has been replaced by 10 second thread blocks and seemingly random C++ exceptions, so it's far from being fixed. Performance is better single-threaded.

Darren's reply is incorrect - I've stepped through our render calls countless times trying to fix this, and the deadlock comes on the HtmlToPdf.StaticRenderHtmlAsPdf call, not on a PdfDocument.Merge call. It's a threading issue.

I suggest avoiding IronPdf if you haven't already bought their product. Find another solution.

abagonhishead
  • 300
  • 3
  • 6
3

I used IronPDF on the 2021.9.3737 branch without any threading issues on windows and Linux today thanks to Darren's help in another thread.

I agree with abagonhishead that StaticRenderHtmlAsPdf used to create a que of PDF documents to be rendered, and on an under-provisioned server it ended in a thread deadlock... the que getting longer and longer as the server struggled to render PDFs.

Solution that worked for me:

  • moving to a well provisioned server (Azure B1 for example)
  • (and/or) moving to IronPDF latest Nuget 2021.9.3737
Stephanie
  • 600
  • 13
  • 24
  • 1
    I managed to deadlock IronPdf.EAP v2021.5.1.1. I have not tried the latest v2021.6.3 hopefully it's fixed. Good note about the under-provisioned server. I'm running my tests on such a server. – Snæbjørn Jul 19 '21 at 08:58
  • Totally Snæbjørn. Rendering a web page to a PDF takes Desktop lever power. I had to look at my server secs. If i wouldn't run chrome on the server all day... why would i expect Html to PDF to work (facepalm https://ironpdf.com/docs/questions/azure/ ) – Stephanie Jul 20 '21 at 02:41
  • 4
    I updated to IronPdf 2021.9.3737 and it appears to have fixed the deadlock issue – Snæbjørn Oct 01 '21 at 13:04
2

Support for Iron Software here.

Our engineers tested your sample project, increasing to 150 iterations and saw it running without issue.

Our expectation of your use-case is that you are creating multiple threads to generate PDF files and store these files into an array for merging later?

Assuming this is the case, the likely cause of this issue is sending too large an array to the merge method, which requires a large amount of RAM to process. The crash is the memory not handling the large number of PDFS to merge.

darren
  • 475
  • 4
  • 15
  • Server provisioning: If i tried to open 150 tabs in chrome on an over powered desktop PC i expect it to crash or freeze. If i automate the opening 150 browser 'tabs' on a much less powerful server ... do i expect instant, stable outcomes?? – Stephanie Aug 16 '21 at 06:43
  • 4
    @darren I updated my sample project to IronPdf 2021.9.3737 and I can confirm that it now works :) – Snæbjørn Oct 01 '21 at 13:08
  • hello, @darren! it seems, im stuck with the same deadlock issue on MacOS with M1. x64 runtime, dotnet6, version 2022.9.9049. (works on windows) – Sam Sch Sep 22 '22 at 00:03
  • MacOs does not work well with CEF, which requires that the original UI thread is never destroyed/changed. This requirement does not exist on Windows or Linux. ASP.NET sometimes cycles to a different thread when a new request is made and as a result, this request will hang as Chrome is unable to process the work. Workaround is to essentially creates a persistent thread for Chrome and performs HTML-to-PDF work on that thread. See https://github.com/Waytal/IronPDFIssue/pulls?q=is%3Apr+is%3Aclosed – darren Sep 22 '22 at 07:34
1

as you can see from the attached image, I tested your code with 1000 iterations and it works without issues, I believe the problem may occur when you increase the iterations or input big HTML size that reaches the max CPU and memory capacity that can't handle. also, I don't agree with abagonhishead because there is not an alternative solution in the market that offer all these features

enter image description here