Регистрация времени выполнения – Конвертация HTML – С#

В этой статье вы найдете пример использования пользовательских обработчиков сообщений для конвертации HTML из ZIP-архива в PDF и регистрации времени выполнения этого преобразования.

Иногда для оптимизации производительности может потребоваться узнать время выполнения веб-запроса. Например, вы хотите знать, сколько времени уходит на преобразование HTML из ZIP-архива в PDF.

Конвертировать HTML из ZIP-архива в PDF – регистрация времени выполнения

Создание обработчика сообщений для пользовательской реализации схемы

Давайте создадим собственный обработчик, который вы можете использовать для реализации пользовательской схемы (протокола). Сделайте следующие шаги:

  1. Используйте необходимое пространство имен, которым является Aspose.Html.Net.
  2. Определите свой собственный класс CustomSchemaMessageHandler, который будет производным от класса MessageHandler.
  3. Инициализируйте экземпляр класса CustomSchemaMessageHandler и определите для него свойство Filter.
  4. Создайте класс CustomSchemaMessageFilter, производный от класса MessageFilter.
  5. Переопределите метод Match() класса MessageFilter для реализации пользовательского поведения обработчика сообщений.

В следующем фрагменте кода показано, как создать класс CustomSchemaMessageHandler:

 1using Aspose.Html.Net;
 2...
 3
 4    // Define the CustomSchemaMessageHandler class that is derived from the MessageHandler class
 5    abstract class CustomSchemaMessageHandler : MessageHandler
 6    {
 7        protected CustomSchemaMessageHandler(string schema)
 8        {
 9            Filters.Add(new CustomSchemaMessageFilter(schema));
10        }
11    }
12
13    // Define the CustomSchemaMessageFilter class that is derived from the MessageFilter class
14    class CustomSchemaMessageFilter : MessageFilter
15    {
16        private readonly string schema;
17        public CustomSchemaMessageFilter(string schema)
18        {
19            this.schema = schema;
20        }
21
22    	// Override the Match() method
23    	public override bool Match(INetworkOperationContext context)
24        {
25            return string.Equals(schema, context.Request.RequestUri.Protocol.TrimEnd(':'));
26        }
27    }

Конструктор CustomSchemaMessageHandler(schema) создает экземпляр объекта CustomSchemaMessageHandler и принимает схему в качестве параметра. Метод Add() добавляет объект CustomSchemaMessageFilter в конец коллекции. Метод Match() проверяет, удовлетворяет ли контекст критериям фильтрации.

Создание ZipFileSchemaMessageHandler для работы с ZIP-архивами

В следующем фрагменте кода показано, как создать класс ZipFileSchemaMessageHandler для работы с ZIP-архивами:

 1using System.IO;
 2using System.Linq;
 3using System.Net;
 4using Aspose.Html;
 5using Aspose.Html.Net;
 6using Aspose.Html.Services;
 7using Aspose.Zip;
 8...
 9
10	// Define the ZipFileSchemaMessageHandler class that is derived from the CustomSchemaMessageHandler class
11	class ZipFileSchemaMessageHandler : CustomSchemaMessageHandler
12	{
13	    private readonly Archive archive;
14
15	    public ZipFileSchemaMessageHandler(Archive archive) : base("zip-file")
16	    {
17	        this.archive = archive;
18	    }
19
20	    // Override the Invoke() method
21	    public override void Invoke(INetworkOperationContext context)
22	    {
23	        var pathInsideArchive = context.Request.RequestUri.Pathname.TrimStart('/').Replace("\\", "/");
24	        var stream = GetFile(pathInsideArchive);
25
26	        if (stream != null)
27	        {
28	            // Checking: if a resource is found in the archive, then return it as a Response
29	            var response = new ResponseMessage(HttpStatusCode.OK);
30	            response.Content = new StreamContent(stream);
31	            response.Headers.ContentType.MediaType = MimeType.FromFileExtension(context.Request.RequestUri.Pathname);
32	            context.Response = response;
33	        }
34	        else
35	        {
36	            context.Response = new ResponseMessage(HttpStatusCode.NotFound);
37	        }
38	
39	        // Invoke the next message handler in the chain
40	        Next(context);
41	    }
42
43	    Stream GetFile(string path)
44	    {
45	        var result = archive
46	            .Entries
47	            .FirstOrDefault(x => x.Name == path);
48	        return result?.Open();
49	    }
50	}
51 

В приведенном выше примере реализован поиск ресурса (zip-архива) по его URI. Если ресурс найден, метод FromFileExtension() возвращает MimeType ресурса.

Обработчик сообщений для регистрации времени выполнения веб-запроса

В следующем фрагменте кода показано, как создать StartRequestDurationLoggingMessageHandler и StopRequestDurationLoggingMessageHandler для регистрации времени, затраченного на выполнение веб-запроса.

 1using System;
 2using System.Collections.Concurrent;
 3using System.Diagnostics;
 4using Aspose.Html;
 5using Aspose.Html.Net;
 6...
 7
 8	// Define the RequestDurationLoggingMessageHandler class that is derived from the MessageHandler class
 9	abstract class RequestDurationLoggingMessageHandler : MessageHandler
10	{
11	    private static ConcurrentDictionary<Url, Stopwatch> requests = new ConcurrentDictionary<Url, Stopwatch>();
12
13	    protected void StartTimer(Url url)
14	    {
15	        requests.TryAdd(url, Stopwatch.StartNew());
16	    }
17
18	    protected TimeSpan StopTimer(Url url)
19	    {
20	        var timer = requests[url];
21	        timer.Stop();
22	        return timer.Elapsed;
23	    }
24	}
25
26	// Create StartRequestDurationLoggingMessageHandler that starts the timer
27	class StartRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
28	{
29	    // Override the Invoke() method
30	    public override void Invoke(INetworkOperationContext context)
31	    {
32	        // Start the stopwatch
33	        StartTimer(context.Request.RequestUri);
34
35	        // Invoke the next message handler in the chain
36	        Next(context);
37	    }
38	}
39
40	// StopRequestDurationLoggingMessageHandler stops the timer
41	class StopRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
42	{
43	    // Override the Invoke() method
44	    public override void Invoke(INetworkOperationContext context)
45	    {
46	        // Stop the stopwatch
47	        var duration = StopTimer(context.Request.RequestUri);
48
49	        // Print the result
50	        Console.WriteLine($"Elapsed: {duration:g}, resource: {context.Request.RequestUri.Pathname}");
51
52	        // Invoke the next message handler in the chain
53	        Next(context);
54	    }
55	}

Добавление обработчиков сообщений в конвейер

Ключевой концепцией работы обработчиков сообщений является объединение их в цепочку. Мы создали несколько обработчиков сообщений и должны добавить их в конвейер в определенном порядке, чтобы реализовать пример регистрации времени преобразования HTML из ZIP-архива в PDF. Выполним следующие шаги:

  1. Создайте экземпляр класса Configuration.
  2. Реализуйте пользовательскую схему ZIP. Используйте метод Add(), чтобы добавить ZipFileSchemaMessageHandler в конец конвейера.
  3. Выполните регистрацию продолжительности. Используйте метод Insert(), чтобы добавить StartRequestDurationLoggingMessageHandler первым в конвейер, и метод Add(), чтобы добавить StopRequestDurationLoggingMessageHandler в конец конвейера.
  4. Инициализировать документ HTML с указанной конфигурацией.
  5. Создайте PDF-устройство и преобразуйте HTML в PDF.
 1using Aspose.Html;
 2using Aspose.Html.Net;
 3using Aspose.Html.Rendering.Pdf;
 4using Aspose.Html.Services;
 5using Aspose.Zip;
 6...
 7
 8    // Prepare path to a source zip file
 9    string documentPath = Path.Combine(DataDir, "test.zip");
10
11    // Prepare path for converted file saving
12    string savePath = Path.Combine(OutputDir, "zip-to-pdf-duration.pdf");
13
14    // Create an instance of the Configuration class
15    using var configuration = new Configuration();
16    var service = configuration.GetService<INetworkService>();
17    var handlers = service.MessageHandlers;
18
19    // Custom Schema: ZIP. Add ZipFileSchemaMessageHandler to the end of the pipeline
20    handlers.Add(new ZipFileSchemaMessageHandler(new Archive(documentPath)));
21
22    // Duration Logging. Add the StartRequestDurationLoggingMessageHandler at the first place in the pipeline
23    handlers.Insert(0, new StartRequestDurationLoggingMessageHandler());
24
25    // Add the StopRequestDurationLoggingMessageHandler to the end of the pipeline
26    handlers.Add(new StopRequestDurationLoggingMessageHandler());
27
28    // Initialize an HTML document with specified configuration
29    using var document = new HTMLDocument("zip-file:///test.html", configuration);
30
31    // Create the PDF Device
32    using var device = new PdfDevice(savePath);
33
34    // Render ZIP to PDF
35    document.RenderTo(device);

Конструктор Configuration() создает экземпляр класса Configuration. После создания конфигурации вызываются методы GetService(), MessageHandlers.Add() и MessageHandlers.Insert(). Методы Insert() и Add() добавляют пользовательские обработчики сообщений в коллекцию существующих обработчиков сообщений. На рисунке показана цепочка обработчиков сообщений для этого примера:

Текст “Цепочка обработчиков сообщений”

Примечание. Конструктор HTMLDocument(address, configuration) принимает абсолютный путь к ZIP-архиву. Но все связанные ресурсы имеют относительные пути в документе HTML и в коде примера.

Вы можете скачать полные примеры и файлы данных с GitHub.

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.