Hello guys.
I've been using pdfsharp for a couple of days and it's really a great framework. Currently, I'm building an app which needs to create a pdf from thousands of images. Everything seems to run ok until I've added some multhitreading to it. Now, whenever I start creating a new pdf file with more than 1800 pages, I start getting an error in the save method. The error occurs in the internal PdfReferenceTable compact method and it says:
an item with the same key has already been added
and the stack trace looks like this (I'm using .net reflector to dig into the method and get the exception):
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value) at PdfSharp.Pdf.PdfReferenceTable.Compact() at PdfSharp.Pdf.PdfDocument.PrepareForSave() at PdfSharp.Pdf.PdfDocument.DoSave(PdfWriter writer) at PdfSharp.Pdf.PdfDocument.Save(Stream stream, Boolean closeStream) at Sra.Digitalizador.pdfs.GeradorPdfs.GetBytesFromDoc(PdfDocument pdfDoc) in D:\projects\SRA\Mercurial\Sra.Core.Projects\Sra.Digitalizador\pdfs\GeradorPdfs.cs:line 102 at Sra.Digitalizador.pdfs.GeradorPdfs.GeraPdfAPartirDeImagens(IList`1 docs) in D:\projects\SRA\Mercurial\Sra.Core.Projects\Sra.Digitalizador\pdfs\GeradorPdfs.cs:line 72 at Sra.Digitalizador.DigitalizacaoViewModel.UploadFile() in D:\projects\SRA\Mercurial\Sra.Core.Projects\Sra.Digitalizador\ViewModel\DigitalizacaoViewModel.cs:line 147 at Sra.Digitalizador.DigitalizacaoViewModel.<.ctor>b__b(Object p) in D:\projects\SRA\Mercurial\Sra.Core.Projects\Sra.Digitalizador\ViewModel\DigitalizacaoViewModel.cs:line 103 at Sra.Digitalizador.Commands.DefaultCommandDispatcher.Execute(Object parameter) in D:\projects\SRA\Mercurial\Sra.Core.Projects\Sra.Digitalizador\Commands\DefaultCommandDispatcher.cs:line 8 at MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(ICommandSource commandSource, Boolean userInitiated) at System.Windows.Controls.Primitives.ButtonBase.OnClick() at System.Windows.Controls.Button.OnClick() at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e) at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent) at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e) at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.Run() at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at Sra.Digitalizador.Startup.Main() in D:\projects\SRA\Mercurial\Sra.Core.Projects\Sra.Digitalizador\Startup.cs:line 45
Can anyone help? can someone tell me what's this ReferenceID property and how it's generated? I'm starting to think that I need to be safe on the pdf generation since it's running several instances of the following code at the same time. here's the method that is run in parallel (pdfpage objects are all created synchronously before starting several taks for generating the contents of each page. not sure if this info is important, but...):
private void AddPage(PdfPage page, DocumentoDigitalizado doc) { BitmapSource img = doc.ImageFile.ToBitmapSource(); using (var graphics = XGraphics.FromPdfPage(page)) { using (var pdfImage = XImage.FromBitmapSource(img)) { var width = img.Width; var height = img.Height; if (page.Width.Point < width) { page.Width = XUnit.FromPoint(width); }
if (page.Height.Point < height) { page.Height = XUnit.FromPoint(height); } graphics.DrawImage(pdfImage, 0, 0, width, height); } } }
thanks, Luis
|