Регистрация времени выполнения – Конвертация HTML – С#
В этой статье вы найдете пример использования пользовательских обработчиков сообщений для конвертации HTML из ZIP-архива в PDF и регистрации времени выполнения этого преобразования.
Иногда для оптимизации производительности может потребоваться узнать время выполнения веб-запроса. Например, вы хотите знать, сколько времени уходит на преобразование HTML из ZIP-архива в PDF.
Конвертировать HTML из ZIP-архива в PDF – регистрация времени выполнения
Создание обработчика сообщений для пользовательской реализации схемы
Давайте создадим собственный обработчик, который вы можете использовать для реализации пользовательской схемы (протокола). Сделайте следующие шаги:
- Используйте необходимое пространство имен, которым является Aspose.Html.Net.
- Определите свой собственный класс CustomSchemaMessageHandler, который будет производным от класса MessageHandler.
- Инициализируйте экземпляр класса CustomSchemaMessageHandler и определите для него свойство Filter.
- Создайте класс CustomSchemaMessageFilter, производный от класса MessageFilter.
- Переопределите метод Match() класса MessageFilter для реализации пользовательского поведения обработчика сообщений.
В следующем фрагменте кода показано, как создать класс CustomSchemaMessageHandler:
1// Define the CustomSchemaMessageFilter class that is derived from the MessageFilter class
2class CustomSchemaMessageFilter : MessageFilter
3{
4 private readonly string schema;
5 public CustomSchemaMessageFilter(string schema)
6 {
7 this.schema = schema;
8 }
9 // Override the Match() method
10 public override bool Match(INetworkOperationContext context)
11 {
12 return string.Equals(schema, context.Request.RequestUri.Protocol.TrimEnd(':'));
13 }
14}
15
16// Define the CustomSchemaMessageHandler class that is derived from the MessageHandler class
17abstract class CustomSchemaMessageHandler : MessageHandler
18{
19 // Initialize an instance of the CustomSchemaMessageHandler class
20 protected CustomSchemaMessageHandler(string schema)
21 {
22 Filters.Add(new CustomSchemaMessageFilter(schema));
23 }
24}
Конструктор CustomSchemaMessageHandler(schema
) создает экземпляр объекта CustomSchemaMessageHandler и принимает схему в качестве параметра. Метод Add() добавляет объект CustomSchemaMessageFilter в конец коллекции. Метод Match() проверяет, удовлетворяет ли контекст критериям фильтрации.
Создание ZipFileSchemaMessageHandler для работы с ZIP-архивами
В следующем фрагменте кода показано, как создать класс ZipFileSchemaMessageHandler для работы с ZIP-архивами:
1// Define the ZipFileSchemaMessageHandler class that is derived from the CustomSchemaMessageHandler class
2class ZipFileSchemaMessageHandler : CustomSchemaMessageHandler
3{
4 private readonly Archive archive;
5
6 public ZipFileSchemaMessageHandler(Archive archive) : base("zip-file")
7 {
8 this.archive = archive;
9 }
10
11 // Override the Invoke() method
12 public override void Invoke(INetworkOperationContext context)
13 {
14 var pathInsideArchive = context.Request.RequestUri.Pathname.TrimStart('/').Replace("\\", "/");
15 var stream = GetFile(pathInsideArchive);
16
17 if (stream != null)
18 {
19 // If a resource is found in the archive, then return it as a Response
20 var response = new ResponseMessage(HttpStatusCode.OK);
21 response.Content = new StreamContent(stream);
22 response.Headers.ContentType.MediaType = MimeType.FromFileExtension(context.Request.RequestUri.Pathname);
23 context.Response = response;
24 }
25 else
26 {
27 context.Response = new ResponseMessage(HttpStatusCode.NotFound);
28 }
29
30 // Invoke the next message handler in the chain
31 Next(context);
32 }
33
34 Stream GetFile(string path)
35 {
36 var result = archive
37 .Entries
38 .FirstOrDefault(x => x.Name == path);
39 return result?.Open();
40 }
41}
В приведенном выше примере реализован поиск ресурса (zip-архива) по его URI. Если ресурс найден, метод FromFileExtension() возвращает MimeType ресурса.
Обработчик сообщений для регистрации времени выполнения веб-запроса
В следующем фрагменте кода показано, как создать StartRequestDurationLoggingMessageHandler и StopRequestDurationLoggingMessageHandler для регистрации времени, затраченного на выполнение веб-запроса.
1// Define the RequestDurationLoggingMessageHandler class that is derived from the MessageHandler class
2abstract class RequestDurationLoggingMessageHandler : MessageHandler
3{
4 private static ConcurrentDictionary<Url, Stopwatch> requests = new ConcurrentDictionary<Url, Stopwatch>();
5
6 protected void StartTimer(Url url)
7 {
8 requests.TryAdd(url, Stopwatch.StartNew());
9 }
10
11 protected TimeSpan StopTimer(Url url)
12 {
13 var timer = requests[url];
14 timer.Stop();
15 return timer.Elapsed;
16 }
17}
18
19class StartRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
20{
21 // Override the Invoke() method
22 public override void Invoke(INetworkOperationContext context)
23 {
24 // Start the stopwatch
25 StartTimer(context.Request.RequestUri);
26
27 // Invoke the next message handler in the chain
28 Next(context);
29 }
30}
31
32class StopRequestDurationLoggingMessageHandler : RequestDurationLoggingMessageHandler
33{
34 // Override the Invoke() method
35 public override void Invoke(INetworkOperationContext context)
36 {
37 // Stop the stopwatch
38 var duration = StopTimer(context.Request.RequestUri);
39
40 // Print the result
41 Debug.WriteLine($"Elapsed: {duration:g}, resource: {context.Request.RequestUri.Pathname}");
42
43 // Invoke the next message handler in the chain
44 Next(context);
45 }
46}
Добавление обработчиков сообщений в конвейер
Ключевой концепцией работы обработчиков сообщений является объединение их в цепочку. Мы создали несколько обработчиков сообщений и должны добавить их в конвейер в определенном порядке, чтобы реализовать пример регистрации времени преобразования HTML из ZIP-архива в PDF. Выполним следующие шаги:
- Создайте экземпляр класса Configuration.
- Реализуйте пользовательскую схему ZIP. Используйте метод Add(), чтобы добавить ZipFileSchemaMessageHandler в конец конвейера.
- Выполните регистрацию продолжительности. Используйте метод Insert(), чтобы добавить StartRequestDurationLoggingMessageHandler первым в конвейер, и метод Add(), чтобы добавить StopRequestDurationLoggingMessageHandler в конец конвейера.
- Инициализировать документ HTML с указанной конфигурацией.
- Создайте PDF-устройство и преобразуйте HTML в PDF.
1// Add this line before you try to use the 'IBM437' encoding
2System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
3
4// Prepare path to a source zip file
5string documentPath = Path.Combine(DataDir, "test.zip");
6
7// Prepare path for converted file saving
8string savePath = Path.Combine(OutputDir, "zip-to-pdf-duration.pdf");
9
10// Create an instance of the Configuration class
11using var configuration = new Configuration();
12var service = configuration.GetService<INetworkService>();
13var handlers = service.MessageHandlers;
14
15// Custom Schema: ZIP. Add ZipFileSchemaMessageHandler to the end of the pipeline
16handlers.Add(new ZipFileSchemaMessageHandler(new Archive(documentPath)));
17
18// Duration Logging. Add the StartRequestDurationLoggingMessageHandler at the first place in the pipeline
19handlers.Insert(0, new StartRequestDurationLoggingMessageHandler());
20
21// Add the StopRequestDurationLoggingMessageHandler to the end of the pipeline
22handlers.Add(new StopRequestDurationLoggingMessageHandler());
23
24// Initialize an HTML document with specified configuration
25using var document = new HTMLDocument("zip-file:///test.html", configuration);
26
27// Create the PDF Device
28using var device = new PdfDevice(savePath);
29
30// Render ZIP to PDF
31document.RenderTo(device);
Конструктор Configuration() создает экземпляр класса Configuration. После создания конфигурации вызываются методы GetService<INetworkService>(), MessageHandlers.Add() и MessageHandlers.Insert(). Методы Insert() и Add() добавляют пользовательские обработчики сообщений в коллекцию существующих обработчиков сообщений. На рисунке показана цепочка обработчиков сообщений для этого примера:
Примечание. Конструктор
HTMLDocument(address, configuration
) принимает абсолютный путь к ZIP-архиву. Но все связанные ресурсы имеют относительные пути в документе HTML и в коде примера.
Вы можете скачать полные примеры и файлы данных с GitHub.