PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Sun Nov 19, 2017 5:41 pm

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Fri Oct 13, 2017 5:09 pm 
Offline

Joined: Tue Jul 26, 2016 5:07 pm
Posts: 19
I've tried to run this code multithreaded, each receiving its own copy of pdfDoc, but getting the exception below. Is it me or the class is not thread safe?

Code:
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = pdfDoc;
renderer.RenderDocument(); // exception thrown here


Code:
System.ArgumentException occurred
  HResult=0x80070057
  Message=An item with the same key has already been added.
  Source=mscorlib
  StackTrace:
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at PdfSharp.Fonts.OpenType.GlyphTypefaceCache.AddGlyphTypeface(XGlyphTypeface glyphTypeface)
   at PdfSharp.Drawing.XGlyphTypeface.GetOrCreateFrom(String familyName, FontResolvingOptions fontResolvingOptions)
   at PdfSharp.Drawing.XFont.Initialize()
   at PdfSharp.Drawing.XFont..ctor(String familyName, Double emSize, XFontStyle style, XPdfFontOptions pdfOptions)
   at MigraDoc.Rendering.FontHandler.FontToXFont(Font font, PdfFontEncoding encoding)
   at MigraDoc.Rendering.ParagraphRenderer.get_CurrentFont()
   at MigraDoc.Rendering.ParagraphRenderer.CalcCurrentVerticalInfo()
   at MigraDoc.Rendering.ParagraphRenderer.InitFormat(Area area, FormatInfo previousFormatInfo)
   at MigraDoc.Rendering.ParagraphRenderer.Format(Area area, FormatInfo previousFormatInfo)
   at MigraDoc.Rendering.TopDownFormatter.FormatOnAreas(XGraphics gfx, Boolean topLevel)
   at MigraDoc.Rendering.FormattedCell.Format(XGraphics gfx)
   at MigraDoc.Rendering.TableRenderer.FormatCells()
   at MigraDoc.Rendering.TableRenderer.InitFormat(Area area, FormatInfo previousFormatInfo)
   at MigraDoc.Rendering.TableRenderer.Format(Area area, FormatInfo previousFormatInfo)
   at MigraDoc.Rendering.TopDownFormatter.FormatOnAreas(XGraphics gfx, Boolean topLevel)
   at MigraDoc.Rendering.FormattedHeaderFooter.Format(XGraphics gfx)
   at MigraDoc.Rendering.FormattedDocument.FormatHeader(HeaderFooterPosition hfp, HeaderFooter header)
   at MigraDoc.Rendering.FormattedDocument.FormatHeadersFooters()
   at MigraDoc.Rendering.FormattedDocument.MigraDoc.Rendering.IAreaProvider.GetNextArea()
   at MigraDoc.Rendering.TopDownFormatter.FormatOnAreas(XGraphics gfx, Boolean topLevel)
   at MigraDoc.Rendering.FormattedDocument.Format(XGraphics gfx)
   at MigraDoc.Rendering.DocumentRenderer.PrepareDocument()
   at MigraDoc.Rendering.PdfDocumentRenderer.PrepareDocumentRenderer(Boolean prepareCompletely)
   at MigraDoc.Rendering.PdfDocumentRenderer.PrepareRenderPages()
   at MigraDoc.Rendering.PdfDocumentRenderer.RenderDocument()


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 13, 2017 7:28 pm 
Offline
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 304
Location: CCAA
Version 1.50, latest beta?

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 16, 2017 1:57 pm 
Offline

Joined: Tue Jul 26, 2016 5:07 pm
Posts: 19
In which version did you make it thread safe?


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 16, 2017 3:24 pm 
Offline
empira Employee
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 2732
Location: Cologne, Germany
With the beta versions of 1.50 the thread safety was improved.
viewtopic.php?f=2&t=832

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 16, 2017 3:51 pm 
Offline

Joined: Tue Jul 26, 2016 5:07 pm
Posts: 19
We are on 1.50.4000-beta3b nuget package. It's not thread safe.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 16, 2017 4:09 pm 
Offline
empira Employee
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 2732
Location: Cologne, Germany
Beta 3b is old and there are known bugs.

Maybe this workaround can help:
viewtopic.php?f=3&t=3315

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 16, 2017 4:51 pm 
Offline

Joined: Tue Jul 26, 2016 5:07 pm
Posts: 19
But that is the latest nuget package available, am I missing anything?

A side topic: just recently I had an issue with .NET locks not working, and had to replace them with a Mutex, then it worked. Maybe see if you are having the same issue. When dumped to console, the addresses of the supposedly the same static lock object were different among threads.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 16, 2017 7:30 pm 
Offline

Joined: Tue Jul 26, 2016 5:07 pm
Posts: 19
Just re-tested with the latest beta and it did not work, nothing saved after rendering. So no, not thread safe.


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 17, 2017 6:13 am 
Offline
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 304
Location: CCAA
vorobej wrote:
A side topic: just recently I had an issue with .NET locks not working, and had to replace them with a Mutex, then it worked. Maybe see if you are having the same issue.
PDFsharp uses Locks to sync font creation/registration. If Locks do not work then PDFsharp is not thread-safe.
Using a single thread to register all required fonts, then using multiple threads to create PDF files would still be a suitable workaround. Replacing the Locks with Mutexes would be another option.

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Tue Oct 17, 2017 2:01 pm 
Offline

Joined: Tue Jul 26, 2016 5:07 pm
Posts: 19
The point is that you may have to abandon Monitor and replace it with try/finally for a Mutex public read only instance field of a Document that renderer is working with, and that will make your code really thread safe.
Just dump the address of the object you lock on from each thread and see if that physical address is the same - if it's different, locks are not working.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 20, 2017 2:11 pm 
Offline

Joined: Tue Jul 26, 2016 5:07 pm
Posts: 19
It baffles me why this is even an issue, as in my case each thread has its own instance of Document, and its own instance of PdfDocumentRenderer. I would understand if there was an issue multi-threading the same instance of a Document, but in my case there should be no sections of code to protect with locks at all.
Can any one of the dev team comment on this, as what I am observing does not make any sense.


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 20, 2017 4:13 pm 
Offline

Joined: Tue Jul 26, 2016 5:07 pm
Posts: 19
Okay, I am more and more convinced, that you are having the exact same issue I faced and described earlier: you are locking on a member of a static class. This did not work in the library I was fixing recently, and I used a Mutex, then it worked. But I ended up moving the object to lock on to the instance of the class we were working with and then it worked again. Do not lock on Lock.FontFactory - lock on the PdfDocumentRenderer or Document instance, and then it should work. And do not use Lock class, you are duplicating lock() function which is a cleaner equivalent, it does exactly the same try/finally with the Monitor without the overhead of writing boilerplate code. I am afraid I cannot spend any more time on this so do as you wish.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group