When calling a PDF export in a high-concurrency environment the internal state can get corrupted because it uses a non-thread safe collection internally.
Sample code:
void WriteToPdf(RadFlowDocument document, Stream outputStream) {
PdfFormatProvider pdfWriter = new() {};
pdfWriter.Export(document, outputStream);
}
When calling it like this:
Parallel.ForEachAsync(listOfDocuments, (document, _) => { WriteToPdf(document, Stream.Null); });
An exception may occur:
System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.
at System.Collections.Generic.Dictionary`2.FindValue(TKey key)
at Telerik.Windows.Documents.Fixed.Model.Fonts.FontsRepository.TryCreateFont(FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontBase& font)
at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Utils.Extensions.CopyPropertiesFrom(CharacterProperties fixedProperties, PdfExportContext context, CharacterProperties properties)
at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Export.PdfExporter.CreateListLevel(ListLevel flowLevel)
at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Export.PdfExporter.CreateList(List flowList)
at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Export.PdfExporter.ExportDocument(RadFlowDocument document, RadFixedDocumentEditor editor)
at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Export.PdfExporter.ExportInternal()
at Telerik.Windows.Documents.Common.FormatProviders.FormatProviderBase`1.Export(T document, Stream output)
at xxxxx.Application.Common.PdfGeneration.PdfWriter.WriteToPdf(RadFlowDocument document, Stream outputStream)
The state is then corrupted forever, until the application is restarted.
Realistic scenario where this is also reproduced: Web application that generates PDFs and is called concurrently.