rdvojmoc / DinkToPdf

C# .NET Core wrapper for wkhtmltopdf library that uses Webkit engine to convert HTML pages to PDF.
MIT License
1.08k stars 415 forks source link

First Call from .Net core 2.1, subsequent request hangs #62

Open Raghav-Gowda opened 5 years ago

Raghav-Gowda commented 5 years ago

Hello,

I am working on ASP.NET Core v2.1. I am able to generate PDF for the first time, but subsequent request hangs. Please note, I've declare SynchronizedConverter as singleton in Startup.cs

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        services.AddDbContext<OCDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

        services.AddMvc().AddSessionStateTempDataProvider();
        services.AddSession();

Please suggest how to solve this issue.

MagnusJohansson commented 5 years ago

I am having the same problem. Have you found any solution?

It can easily be reproduced in a console app as well, the second iteration in the loop below, the conversion will hang:

    static void Main(string[] args)
        {
            var doc = new HtmlToPdfDocument()
            {
                GlobalSettings =
                {
                    ColorMode = ColorMode.Color,
                    Orientation = Orientation.Portrait,
                    PaperSize = PaperKind.A4,
                },
                Objects =
                {
                    new ObjectSettings()
                    {
                        PagesCount = true,
                        HtmlContent = @"Lorem ipsum dolor sit amet",
                        WebSettings =
                        {
                            DefaultEncoding = "utf-8"
                        },
                        HeaderSettings =
                        {
                            FontSize = 9, Right = "Page [page] of [toPage]", Line = true, Spacing = 2.812
                        }
                    }
                }
            };

            for (int i = 0; i < 2; i++)
            {
                var converter = new SynchronizedConverter(new PdfTools());
                byte[] pdfData = converter.Convert(doc);
            }

        }
MagnusJohansson commented 5 years ago

One possible workaround can be to instantiate a new BasicConverter for each request and force the PdfTools object to dispose and unload the libraries after each request in a ASP.NET controller, like this:

[Produces(MediaTypeNames.Application.Pdf)]
public async Task<IActionResult> Index()
{
    var doc = new HtmlToPdfDocument()
    {
        GlobalSettings =
        {
            ColorMode = ColorMode.Color,
            Orientation = Orientation.Portrait,
            PaperSize = PaperKind.A4,
        },
        Objects =
        {
            new ObjectSettings()
            {
                PagesCount = true,
                HtmlContent = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In consectetur mauris eget ultrices  iaculis.",
                WebSettings = { DefaultEncoding = "utf-8" },
                HeaderSettings = { FontSize = 9, Right = "Page [page] of [toPage]", Line = true, Spacing = 2.812 }
            }
        }
    };

    using (var tools = new PdfTools())
    {
        var converter = new BasicConverter(tools);
        byte[] pdfData = converter.Convert(doc);
        return File(pdfData, MediaTypeNames.Application.Pdf);
    }
}
MagnusJohansson commented 5 years ago

I spoke too soon. This is not a valid work around because;

What a mess this is.

mze9412 commented 5 years ago

It seems to work for me after switching to the newest version of wkhtmltopdf (see also this PR) https://github.com/rdvojmoc/DinkToPdf/pull/59

HakanL commented 5 years ago

I upgraded to 0.12.5 of the 64-bit Windows library and it still hangs on the second request, so PR #59 didn't help me. However, I realized I was creating multiple instances of SynchronizedConverter, once I changed to a singleton then it actually works fine.

caldus85 commented 5 years ago

I upgraded to 0.12.5 of the 64-bit Windows library and it still hangs on the second request, so PR #59 didn't help me. However, I realized I was creating multiple instances of SynchronizedConverter, once I changed to a singleton then it actually works fine.

This fixed the issue for me. Thanks!

Alexander-Lazarov88 commented 4 years ago

If someone still has this issue, can try to remove this 'var converter = new SynchronizedConverter(new PdfTools());' and just inject 'IConverter' in your service. I try and this approach is working, after all, we already register the converter, we don`t need to create an instance with 'new' keyword.

asimon91 commented 4 years ago

I confirm too that changing to singleton instead of multiple instances works flawlessly. Thank you!

renatolopes commented 3 years ago

When i call in the integration tests, in second test that calls convert i'm with same issue even follow the instructions and using singleton injection. Any tips?

caldus85 commented 3 years ago

When i call in the integration tests, in second test that calls convert i'm with same issue even follow the instructions and using singleton injection. Any tips?

I would try version 0.12.5 above if you are not already. Then double check that you're calling services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));. Also note Alexander-Lazarov88's comment above about possibly using IConverter instead. Beyond that I don't have any other ideas, sorry.

zbex commented 1 year ago

When i call in the integration tests, in second test that calls convert i'm with same issue even follow the instructions and using singleton injection. Any tips?

Any luck with this? I experience the same issue.