Проблемы с конвертацией PDF в SVG через Aspose.Pdf при параллельной обработке

опишу проблему:

Есть задача по конвертации pdf страниц в svg и png файлы.

Есть код, который успешно реализует данную задачу при последовательной обработке всех файлов. Проблема возникает, когда я пытаюсь распараллелить выполнение конвертации для нескольких файлов одновременно. Библиотека aspose.pdf не до конца конвертирует pdf в svg (рандомно обрезает страницу).Запускаю одни и те же документы, получаю рандомно некорректно сконвертированные файлы. Притом сам файл svg открывается без ошибок, просто часть линий или текста не переносятся в svg из pdf. При последовательной обработке файлов такой проблемы не возникает. У меня подозрение, что я неправильно реализую распараллеливание для асинхронных задач, код ниже.

public async Task<JobContract> ProcessingByContractParallel(JobContract jobContract)
    {
        try
        {
            foreach (var trmPackage in jobContract.TrmPackages)
            {
                var tempFolder = !string.IsNullOrWhiteSpace(jobContract.TempFolder)
                    ? jobContract.TempFolder
                    : Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                var outputDirectoryInfo = new DirectoryInfo(Path.Combine(tempFolder, jobContract.QueueItemId.ToString(), String.Concat(trmPackage.TrmName, "_", Path.GetRandomFileName())));
                if (!outputDirectoryInfo.Exists) outputDirectoryInfo.Create();

                trmPackage.TrmSplittedFilesPath = outputDirectoryInfo.FullName;
                _logger.LogInformation($"Путь до временных файлов: {outputDirectoryInfo.FullName}");

                var options = new ParallelOptions { MaxDegreeOfParallelism = 4};
                
//здесь пытаюсь добиться распараллеливания обработки файлов
//без проблем отрабатывает запуск foreach (var pdfFile in trmPackage.ArrayOfPdfFiles)

                await Parallel.ForEachAsync(trmPackage.ArrayOfPdfFiles, options,async (pdfFile,defult) =>
                {
                    var fullPathPdfFile = Path.Combine(trmPackage.TrmPath, pdfFile.FileName);

                    pdfFile.FileSize = new FileInfo(fullPathPdfFile).Length;

                    var splitResults = new List<FileOperationResult>();

                    try
                    {
                        splitResults = (await _pdfSplitterService.SplitAndSavePageAsPdf(outputDirectoryInfo.FullName, fullPathPdfFile))
                        .ToList();
                    }
                    catch (Exception ex)
                    {
                        var fileOperationResultErr = FileOperationResult.CreateFailure("Faulted", ex);
                        splitResults.Add(fileOperationResultErr);
                    }

                    foreach (var splitResult in splitResults)
                    {
                        if (splitResult.HasError)
                        {
                            pdfFile.PagesInfo.Add(new PageInfo
                            {
                                SplitPDFPageName = splitResult.FileName,
                                SplitSVGPageName = "",
                                SplitPNGPageName = "",
                                PageStatusError = splitResult.HasError,
                                PageExceptionMsg = splitResult.NonSuccessMessage,
                                SplitPageNumber = splitResults.IndexOf(splitResult) + 1
                            });
                        }
                        else
                        {

                            try
                            {
                                //конвертируем и устанавливаем ожидаемое время выполнения в 30 мин
                            //проблема возникает с методом ConvertOnePagesPdfToSvgWithCt
                                var convertSvgResult = await _pdfConverterService.ConvertOnePagesPdfToSvgWithCt(outputDirectoryInfo.FullName, splitResult.FullFileName);
                                var convertPngResult = await _pdfConverterService.ConvertOnePagesPdfToPngWithCt(outputDirectoryInfo.FullName, splitResult.FullFileName);

                                


                                pdfFile.PagesInfo.Add(new PageInfo
                                {
                                    SplitPDFPageName = splitResult.FileName,
                                    SplitSVGPageName = convertSvgResult.FileName,
                                    SplitPNGPageName = convertPngResult.FileName,
                                    PageStatusError = splitResult.HasError || convertSvgResult.HasError || convertPngResult.HasError,
                                    PageExceptionMsg = splitResult.NonSuccessMessage + convertSvgResult.NonSuccessMessage + convertPngResult.NonSuccessMessage,
                                    SplitPageNumber = splitResults.IndexOf(splitResult) + 1
                                });
                            }
                            catch (Exception ex)
                            {
                                pdfFile.PagesInfo.Add(new PageInfo
                                {
                                    SplitPDFPageName = splitResult.FileName,
                                    SplitSVGPageName = "",
                                    SplitPNGPageName = "",
                                    PageStatusError = splitResult.HasError,
                                    PageExceptionMsg = ex.Message,
                                    SplitPageNumber = splitResults.IndexOf(splitResult) + 1
                                });
                            }
                        }
                    }
                });

            }

            return jobContract;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "ProcessingByContract");
            return jobContract;
        }
    }

Сам проблемный метод:

public async Task<FileOperationResult> ConvertOnePagesPdfToSvgWithCt(string outputFolder, string? fullPdfFileName)
    {
        var outputFileName = $"{Path.GetFileNameWithoutExtension(fullPdfFileName)}.svg";
        _logger.LogInformation($"Convert to Svg - {Path.GetFileName(fullPdfFileName)}");

        try
        {

            using var cts = new CancellationTokenSource();
            cts.CancelAfter(_convertSetting.Value.ConvertTimeoutMs);
            
            var task = Task.Run(async() =>
            {
                try
                {

                    var pdfPage = new Pdf(fullPdfFileName);

                    //сама конвертация
                    await pdfPage.SaveAsSvgAsync(Path.Combine(outputFolder, outputFileName), cts.Token);
                }
                catch
                {
                    cts.Cancel();

                }


            }, cts.Token);



            await  task.WaitAsync(cts.Token);

            if (task.IsCanceled)
            {
                _logger.LogWarning($"Операция конвертации прервана для файла:{Path.GetFileName(fullPdfFileName)}");
                return FileOperationResult.CreateFailure(outputFileName, new TimeoutException("Превышено время ожидания задачи или ошибка ковертации"));
            }
            else
            {
                return FileOperationResult.CreateSuccessResult(outputFileName);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, message: $"ERROR Converting pdf '{fullPdfFileName}' as SVG");
            return FileOperationResult.CreateFailure(outputFileName, ex);
        }
    }

Конвертация сторонней библиотекой

public async Task<string> SaveAsSvgAsync(string outputFilename, CancellationToken cts, bool removeWatermark = true)
        {
            try
            {
                try
                {
                    var document = new Aspose.Pdf.Document(Filestream, false);
                    await document.SaveAsync(outputFilename, Aspose.Pdf.SaveFormat.Svg, cts);

                    if (removeWatermark) // remove watermark
                    {
                        var svgTextLines = await File.ReadAllTextAsync(outputFilename);
                        var svgClearText = Regex.Replace(svgTextLines, @"(<text)(.)+(Evaluation)(.)+(Aspose)(.)+(<\/text>)", "");
                        //var svgClearText = Regex.Replace(svgTextLines, @"[\n\r\t]+?((<text)(.)+[\n\r]+?(Evaluation)(.)+(Aspose)(.)+[\n\r]+?(.)+(<\/text>))[\n\r\t]*", "");
                        await File.WriteAllTextAsync(outputFilename, svgClearText);
                    }
                }
                catch
                {
                    var document = new Spire.Pdf.PdfDocument(Filestream);
                    document.SaveToFile(outputFilename, Spire.Pdf.FileFormat.SVG);

                    if (removeWatermark) // remove watermark
                    {
                        var svgTextLines = await File.ReadAllTextAsync(outputFilename);
                        var svgClearText = Regex.Replace(svgTextLines, @"(<text)(.)+(Evaluation)(.)+(Aspose)(.)+(<\/text>)", "");
                        //var svgClearText = Regex.Replace(svgTextLines, @"[\n\r\t]+?((<text)(.)+[\n\r]+?(Evaluation)(.)+(Aspose)(.)+[\n\r]+?(.)+(<\/text>))[\n\r\t]*", "");
                        await File.WriteAllTextAsync(outputFilename, svgClearText);
                    }
                }
            }
            catch
            {
                throw;
            }

            return outputFilename;
        }

Ответы (0 шт):