Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi threading the Document Rendering #11

Closed
ajos6183 opened this issue May 3, 2018 · 5 comments
Closed

Multi threading the Document Rendering #11

ajos6183 opened this issue May 3, 2018 · 5 comments
Labels

Comments

@ajos6183
Copy link

ajos6183 commented May 3, 2018

Hi @ThomasHoevel / @StLange

This is only a question. I am using the following code to render the PDF document and at the same time monitor the progress. I have removed the progress monitoring code for simplicity.

    Dim pdfRenderer = New PdfDocumentRenderer(True) With {.Document = report}
    pdfRenderer.PrepareRenderPages()
    For i As Integer = 1 To pdfRenderer.DocumentRenderer.FormattedDocument.PageCount
        Dim page = pdfRenderer.PdfDocument.AddPage()
        Dim pageInfo As PageInfo = pdfRenderer.DocumentRenderer.FormattedDocument.GetPageInfo(i)
        page.Width = pageInfo.Width
        page.Height = pageInfo.Height
        page.Orientation = pageInfo.Orientation
        Using gfx As PdfSharp.Drawing.XGraphics = PdfSharp.Drawing.XGraphics.FromPdfPage(page)
            gfx.MUH = If(pdfRenderer.Unicode, PdfFontEncoding.Unicode, PdfFontEncoding.WinAnsi)
            pdfRenderer.DocumentRenderer.RenderPage(gfx, i)
        End Using
    Next
    pdfRenderer.PdfDocument.PageLayout = PdfSharp.Pdf.PdfPageLayout.SinglePage

The PDF document is around 3500 pages. It takes about 130 seconds to prepare the pages and another 100 seconds to render. Is there a way i can incorporate multi threading to speed things up? My simplistic attempts to do that for the rendering have failed.

Thanks,
Anthony

@ajos6183
Copy link
Author

Is anyone able to help with this?

@TH-Soft
Copy link
Contributor

TH-Soft commented May 17, 2018

Anyone now? The original question is aimed at two persons only.

Not my area of expertise. No definite answer, just some guesses.
Currently a new section starts on a new page. It could be possible to use multi-threading for the layout process using one thread for each section.
It should be possible to render multi-threaded using one thread per page, but it may be necessary to add pages single-threaded (using a semaphore).
I don't know if rendering is thread-safe. This may require changes in MigraDoc or PDFsharp.
There are some locks in the font management of PDFsharp, but multi-threading was not yet tested intensively.
You ask if you can do it. I cannot judge your abilities. I'm sure it can be done in general. I'm not sure if I can do it. I cannot guess how long it would take me.

@ajos6183
Copy link
Author

Thank you for your help. I appreciate it. I will try your suggestions.

@TH-Soft
Copy link
Contributor

TH-Soft commented May 17, 2018

Things are a bit more complicated than I realised one hour ago.
I guess you have to serialise all calls that lead to new objects in the PDF file.

Pages: You can easily serialise these calls in your code: call AddPage() for all pages before starting the first render thread.

Fonts: There are unverified reports that the locking mechanism for fonts in PDFsharp was not working. Known workaround: Use a single thread to create a dummy PDF that uses all the fonts you will ever need.
If your MigraDoc document uses e.g. Arial, Courier, and Times, then create a page with text in Arial Regular, Arial Bold, Arial Italic, Arial Bold Italic, Courier Regular, Courier Bold and so forth.
It might be worth using the workaround even if it is not needed for fonts as this might simplify dealing with other object types.

Images: I would tackle this by adding a Lock to any DrawImage call in the XGraphics class.

Other objects: There could be more objects I do not currently think of. Use the same lock you also use for images if there are any other objects.

As always: It could be simpler to get it working for specific MigraDoc documents that use limited features than making a general implementation that works for all MigraDoc features.

@ajos6183
Copy link
Author

Thanks for the follow up comments. When i get to it, i will research what you explained and try to implement it.

emazv72 added a commit to emazv72/MigraDoc that referenced this issue Aug 26, 2020
# This is the 1st commit message:
Introduce xml format for serialization and deserialzion

# This is the commit message empira#2:

Update README.md
# This is the commit message empira#3:

Comment fix for release build

# This is the commit message empira#4:

xml parser fix

# This is the commit message empira#5:

last page header and footer

# This is the commit message empira#6:

footer fix

# This is the commit message empira#7:

upgrade README.md

# This is the commit message empira#8:

Update README.md
# This is the commit message empira#9:

last page header footer rendering fix

# This is the commit message empira#10:

ListInfo fix serialization

# This is the commit message empira#11:

paragraph parsing fix

# This is the commit message empira#12:

text parser fix

# This is the commit message empira#13:

support para break

# This is the commit message empira#14:

CDATA parser fix

# This is the commit message empira#15:

rounded corner radius for table cells

# This is the commit message empira#16:

makes DifferentLastPageHeaderFooter  section aware

# This is the commit message empira#17:

fix cell serialization

# This is the commit message empira#18:

Avoid rendering failure images

# This is the commit message empira#19:

barcode rendering

# This is the commit message empira#20:

doc fix

# This is the commit message empira#21:

support barcode elements inside a paragraph

# This is the commit message empira#22:

barcode rendering fix

# This is the commit message empira#23:

amend README.md

# This is the commit message empira#24:

fix readme

# This is the commit message empira#25:

fix readme
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants