Обработка преобразования HTML в PDF занимает много времени с использованием библиотеки DinkToPdf - PullRequest
0 голосов
/ 21 февраля 2019

Обработка преобразования HTML в PDF занимает много времени с использованием библиотеки DinkToPdf, когда эта строка кода запускается: ConverterToPdf.Convert(pdf)

Как решить эту проблему?

public byte[] ConvertReportToPDFAsync<TViewModel>() where TViewModel : new()
{
   var globalSettings = new GlobalSettings
   {
      ColorMode = ColorMode.Color,
      Orientation = Orientation.Portrait,
      PaperSize = PaperKind.A4,
      Margins = new MarginSettings { Top = 10 },
      DocumentTitle = documentTitle,
   };

   var objectSettings = new ObjectSettings
   {
      PagesCount = true,
      HtmlContent =@"<html><body><div>Hello</div></body></html>",
      WebSettings = { DefaultEncoding = "utf -8", UserStyleSheet = Path.Combine(Directory.GetCurrentDirectory(), "assets", "PruefReportDataTableFormat.css") },
      HeaderSettings = { FontName = "Arial", FontSize = 9, Right = "Page [page] of [toPage]", Line = true },
      FooterSettings = { FontName = "Arial", FontSize = 9, Line = true, Center = "Report Footer" }
    };
    var pdf = new HtmlToPdfDocument()
    {
       GlobalSettings = globalSettings,
       Objects = { objectSettings }
    };

   byte[] file = ConverterToPdf.Convert(pdf); // TOO LONG PROCESS !!!!

   return file;

}

Класс запуска:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpContextAccessor(); 
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddMemoryCache(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddSessionStateTempDataProvider();

        services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools())); // DinkToPdf
    }
}

Обновлено:

После трассировки я выяснил, что проблема в WkHtmlToXBindings.wkhtmltopdf_convert метод в namespace DinkToPdf

namespace DinkToPdf
{
   public sealed class PdfTools : ITools, IDisposable
   {
      // some codes
      public bool DoConversion(IntPtr converter)
      {
         return WkHtmlToXBindings.wkhtmltopdf_convert(converter); // ACTUALLY TOO LONG PROCESS OCCURS HERE !!!!
      }
   }
}

Обновление 2:

После глубокой трассировки я понял, чтов этой строке кода Monitor.Wait((object) task1); произошел длительный процесс! (я не могу изменить этот код, поскольку этот код является частью dinktopdf.dll файла.)

namespace DinkToPdf
{
   public class SynchronizedConverter : BasicConverter
   {
      public TResult Invoke<TResult>(Func<TResult> @delegate)
      {
         this.StartThread();
         Task<TResult> task1 = new Task<TResult>(@delegate);
         Task<TResult> task2 = task1;
         bool lockTaken = false;
         try
         {
             Monitor.Enter((object) task2, ref lockTaken);
             this.conversions.Add((Task) task1);
             Monitor.Wait((object) task1);   //Bottleneck!! LONG PROCESS!!
         }
         finally
         {
            if (lockTaken)
               Monitor.Exit((object) task2);
         }
         if (task1.Exception != null)
            throw task1.Exception;
         return task1.Result;
      }
   }
}
...