Asynchronous Conversion | |
SelectPdf Html To Pdf Converter for .NET can convert asynchronously. While a web page loads and renders, no thread is held waiting for it, so a web application can have many conversions in flight without a thread for each, and several pages can be rendered at the same time from one method with await Task.WhenAll(...).
An asynchronous conversion produces the same document as the synchronous one. The asynchronous methods are:
ConvertUrlAsync - converts a web page, with an overload that takes a CancellationToken.
ConvertHtmlStringAsync - converts a html string, with or without a base url, and with overloads that take a CancellationToken.
ConvertUrlAsync and ConvertHtmlStringAsync - the same for html to image.
AddAsync - adds an element to a page or a template without waiting for it to render (see below).
One HtmlToPdf object runs one conversion at a time: use a converter for each conversion that runs at the same time. Conversions started together render at the same time, up to MaximumConcurrentConversions; the ones past that limit wait for their turn in the order they were started, in the same queue as the synchronous conversions.
string[] urls = { "https://selectpdf.com", "https://selectpdf.com/pricing/", "https://selectpdf.com/html-to-pdf-api/" }; PdfDocument[] docs = await Task.WhenAll(urls.Select(url => { HtmlToPdf converter = new HtmlToPdf(); converter.Options.PdfPageSize = PdfPageSize.A4; return converter.ConvertUrlAsync(url); })); for (int i = 0; i < docs.Length; i++) { docs[i].Save("page" + i + ".pdf"); docs[i].Close(); }
A conversion with html in its header or footer (PdfHtmlSection) renders the header and the footer beside the page itself, synchronously or not, so they add little to the conversion time.
Cancelling the token stops the conversion wherever it is: a conversion still waiting for its turn leaves the queue, and one that is rendering is stopped in the engine. The task then ends cancelled and no document is produced. A token with a timeout is a simple way to bound how long a conversion may take.
using (CancellationTokenSource timeout = new CancellationTokenSource(TimeSpan.FromSeconds(30))) { HtmlToPdf converter = new HtmlToPdf(); try { PdfDocument doc = await converter.ConvertUrlAsync("https://selectpdf.com", timeout.Token); doc.Save("document.pdf"); doc.Close(); } catch (OperationCanceledException) { // the conversion took longer than 30 seconds } }
A document built from several html elements (PdfHtmlElement, HtmlToImageElement) can render them all at the same time with AddAsync. Each element starts rendering as soon as it is added, and the elements are placed in the document one after the other, in the order they were added, as they would be with Add(PdfPageElement).
Until an element has been placed, its position in the document is not known. An element positioned from the result of another one - for example right below its PdfPageLastRectangle - must await that element first, or be placed on a page of its own. Saving, closing or appending the document, a synchronous Add and the members of Pages wait for the pending additions before they run.
PdfDocument doc = new PdfDocument(); PdfPage page1 = doc.AddPage(); PdfPage page2 = doc.AddPage(); // both regions render at the same time Task<PdfRenderingResult> first = page1.AddAsync(new PdfHtmlElement("https://selectpdf.com")); Task<PdfRenderingResult> second = page2.AddAsync(new PdfHtmlElement("https://selectpdf.com/pricing/")); // a text placed below the first region waits for it PdfRenderingResult result = await first; PdfFont font = doc.Fonts.Add(PdfStandardFont.Helvetica); font.Size = 10; await page1.AddAsync(new PdfTextElement(0, result.PdfPageLastRectangle.Bottom + 10, "Captured with SelectPdf", font)); await second; doc.Save("document.pdf"); doc.Close();
Cancelling the token given to AddAsync stops an element that has not been placed yet; the elements added after it are placed as usual. Do not change an element after adding it until its task has completed.