Click or drag to resize
Pdf Library for .NET

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:

Converting several pages at the same time

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 a conversion

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
    }
}
Adding html elements to a document asynchronously

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.

See Also