Регистрация времени выполнения – Конвертация HTML – С#
В этой статье вы найдете пример использования пользовательских обработчиков сообщений для конвертации HTML из ZIP-архива в PDF и регистрации времени выполнения этого преобразования.
Иногда для оптимизации производительности может потребоваться узнать время выполнения веб-запроса. Например, вы хотите знать, сколько времени уходит на преобразование HTML из ZIP-архива в PDF.
Конвертировать HTML из ZIP-архива в PDF – регистрация времени выполнения
Создание обработчика сообщений для пользовательской реализации схемы
Давайте создадим собственный обработчик, который вы можете использовать для реализации пользовательской схемы (протокола). Сделайте следующие шаги:
- Используйте необходимое пространство имен, которым является Aspose.Html.Net.
- Определите свой собственный класс CustomSchemaMessageHandler, который будет производным от класса MessageHandler.
- Инициализируйте экземпляр класса CustomSchemaMessageHandler и определите для него свойство Filter.
- Создайте класс CustomSchemaMessageFilter, производный от класса MessageFilter.
- Переопределите метод 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. Выполним следующие шаги:
- Создайте экземпляр класса Configuration.
- Реализуйте пользовательскую схему ZIP. Используйте метод Add(), чтобы добавить ZipFileSchemaMessageHandler в конец конвейера.
- Выполните регистрацию продолжительности. Используйте метод Insert(), чтобы добавить StartRequestDurationLoggingMessageHandler первым в конвейер, и метод Add(), чтобы добавить StopRequestDurationLoggingMessageHandler в конец конвейера.
- Инициализировать документ HTML с указанной конфигурацией.
- Создайте 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
Примечание. Конструктор
HTMLDocument(address, configuration
) принимает абсолютный путь к ZIP-архиву. Но все связанные ресурсы имеют относительные пути в документе HTML и в коде примера.
Вы можете скачать полные примеры и файлы данных с GitHub.