# Manage Asynchronous Report Rendering

You can manage asynchronous or long-running report rendering at export by controlling such options as display rendering progress, cancel the rendering process, log information on the report execution, etc.

## Content



ActiveReports provides a number of possibilities to control the export process, which can help you create more responsive applications. In this topic, we discuss common use cases of asynchronous or long-running report rendering:

*   Display export progress in a number of pages (ActiveReports can display a total number of pages only once the rendering is complete).
*   Create an Export dialog with the Cancel option.
*   Log information on the report execution.

### Display Progress Information

Let's see how you can have displayed the export rendering progress information, using a WinForms Viewer application. As an example, we will take the **Export** sample that you can access by following this link - [https://github.com/activereports/Samples19/tree/main/API/PageAndRDLX/Export](https://github.com/activereports/Samples19/tree/main/API/PageAndRDLX/Export).

The rendering progress information can be displayed for PDF, Image, HTML, and Excel exports at the report rendering.


> type=note
> **Note**: The progress information is not shown if the report is exported with the **Pagination** property set to False (Image, Excel Rendering Extensions) or with the **Mode** property set to Galley (HTML Rendering Extension).

1.  Open the **Export** sample project.
2.  From the Visual Studio toolbox, drag the **Label** control onto the Form.
3.  Add this code into the Form.
    
    ```vbnet
    Private Async Sub ExportAsync(ByVal report As PageReport, ByVal renderingExtension As IRenderingExtension, ByVal outputProvider As StreamProvider, ByVal settings As NameValueCollection)
       labelExport.Text = "Export started..."
       Dim control = Me 
       Dim progress = New Progress(Of ProgressInfo)(Sub(progressInfo)
          control.BeginInvoke(New MethodInvoker(Sub()
             labelExport.Text = If(progressInfo.IsLast = True, "Export is finished." , $"Exported {progressInfo.PageNumber} pages.")
          End Sub))
       End Sub)
       
       await Task.Run(Sub()
          Try
             report.Document.Render(renderingExtension, outputProvider, settings, False, False, CancellationToken.None, progress)
          Catch e as Exception
          End Try
       End Sub)
    End Sub
    ```
    
    ```csharp
    private async void ExportAsync(PageReport report, IRenderingExtension renderingExtension, StreamProvider outputProvider, NameValueCollection settings)
    {
       labelExport.Text = "Export started...";
       var control = this;
       var progress = new Progress<ProgressInfo>(progressInfo =>
       {
          control.BeginInvoke(new MethodInvoker(() =>
          {
             labelExport.Text = progressInfo.IsLast ? "Export is finished." : $"Exported {progressInfo.PageNumber} pages.";
                
          }));
       });
       await Task.Run(() =>
       {
          try
          {
             report.Document.Render(renderingExtension, outputProvider, settings, false, false, CancellationToken.None, progress);
          }
          catch
          {
             // ignored
          }
       });
    }
    ```
    
4.  Run the project.
5.  In the **Export** form, select PDF, Image, HTML, or Excel export type.
6.  Click the **Export** button and see the progress information in the new label.<br />![Click the Export button in Export Sample Report](https://cdn.mescius.io/document-site-files/images/b298aea2-8cb8-4a0f-be88-4f54aa263ebd/images/export-progress.png)

### Cancel Report Rendering

You can cancel the report rendering or export by using the following code.

```vbnet
Dim _cancellationTokenSource

Private Async Sub ExportAsync(ByVal report As PageReport, ByVal renderingExtension As IRenderingExtension, ByVal outputProvider As FileStreamProvider, ByVal settings As NameValueCollection)
   _cancellationTokenSource = New CancellationTokenSource()
   exportButton.Text = "Cancel"
   RemoveHandler exportButton.Click, AddressOf exportButton_Click
   AddHandler exportButton.Click, AddressOf CancelExport
   Await Task.Run(Sub()
      Try
         report.Document.Render(renderingExtension, outputProvider, settings, False, False, _cancellationTokenSource.Token)
      Catch unusedOperationCanceledException As OperationCanceledException
      End Try
   End Sub)
   If _cancellationTokenSource.IsCancellationRequested Then MessageBox.Show("Export was cancelled", "Export", MessageBoxButtons.OK, MessageBoxIcon.Information)
   _cancellationTokenSource.Dispose()
   _cancellationTokenSource = Nothing
   RemoveHandler exportButton.Click, AddressOf CancelExport
   AddHandler exportButton.Click, AddressOf exportButton_Click
   exportButton.Text = "Export"
End Sub

Private Sub CancelExport(ByVal sender As Object, ByVal e As EventArgs)
   _cancellationTokenSource?.Cancel()
End Sub
```

```csharp
private CancellationTokenSource _cancellationTokenSource;                 
private async void ExportAsync(PageReport report, IRenderingExtension renderingExtension, FileStreamProvider outputProvider, NameValueCollection settings)
{
   _cancellationTokenSource = new CancellationTokenSource();
   exportButton.Text = "Cancel";
   exportButton.Click -= exportButton_Click;
   exportButton.Click += cancelExport;
     
   await Task.Run(() =>
   {
      try
      {
         report.Document.Render(renderingExtension, outputProvider, settings, false, false, _cancellationTokenSource.Token);
      }
      catch (OperationCanceledException)
      {
      }
   });
     
   if (_cancellationTokenSource.IsCancellationRequested)
       MessageBox.Show("Export was cancelled", "Export", MessageBoxButtons.OK, MessageBoxIcon.Information);
   _cancellationTokenSource.Dispose();
   _cancellationTokenSource = null;
   exportButton.Click -= cancelExport;
   exportButton.Click += exportButton_Click;
   exportButton.Text = "Export";
}
     
private void cancelExport(object sender, EventArgs e)
{
   _cancellationTokenSource?.Cancel();
}
```

### Information Logging

To log information on the report rendering, add [Trace Listeners](https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/trace-listeners). As an example, modify the ExportAsync function as follows.

```vbnet
Private Async Sub ExportAsync(ByVal report As PageReport, ByVal renderingExtension As IRenderingExtension, ByVal outputProvider As StreamProvider, ByVal settings As NameValueCollection)
   labelExport.Text = "Export started..."
   Dim control = Me 
   Dim progress = New Progress(Of ProgressInfo)(Sub(progressInfo)
      control.BeginInvoke(New MethodInvoker(Function()
         labelExport.Text = If(progressInfo.IsLast = True, "Export is finished." , $"Exported {progressInfo.PageNumber} pages.")
         Trace.TraceInformation($"Exported {progressInfo.PageNumber} pages.")
      End Function))
   End Sub)
   await Task.Run(Sub()
      Try
         Dim traceWriter = New TextWriterTraceListener("TextWriterOutput.log", "myListener")
         Trace.Listeners.Clear()
         Trace.Listeners.Add(traceWriter)
         report.Document.Render(renderingExtension, outputProvider, settings, False, False, CancellationToken.None, progress)
         Trace.Flush()
         Trace.Listeners.Clear()
      Catch e as Exception
      End Try
   End Sub)
End Sub
```

```csharp
private async void ExportAsync(PageReport report, IRenderingExtension renderingExtension, StreamProvider outputProvider, NameValueCollection settings)
{
   labelExport.Text = "Export started...";
   var control = this;
   var progress = new Progress<ProgressInfo>(progressInfo =>
   {
      control.BeginInvoke(new MethodInvoker(() =>
      {
         labelExport.Text = progressInfo.IsLast ? "Export is finished." : $"Exported {progressInfo.PageNumber} pages.";
         Trace.TraceInformation($"Exported {progressInfo.PageNumber} pages.");
      }));
   });
   await Task.Run(() =>
   {
      try
      {
         var traceWriter = new TextWriterTraceListener("TextWriterOutput.log", "myListener");
         Trace.Listeners.Clear();
         Trace.Listeners.Add(traceWriter);
         report.Document.Render(renderingExtension, outputProvider, settings, false, false, CancellationToken.None, progress);
         Trace.Flush();
         Trace.Listeners.Clear();  
      }
      catch
      {
         // ignored
      }
   });
}
```
