Load and Save Progress Reporting and Cancellation

The following example demonstrates how to output the save progress of a large PowerPoint file to the console, using the GemBox.Presentation component.

using GemBox.Presentation;
using System;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        Console.WriteLine("Creating presentation");

        // Create large presentation.
        var presentation = new PresentationDocument();
        for (var i = 0; i < 10000; i++)
        {
            var slide = presentation.Slides.AddNew();
            var textBox = slide.Content.AddTextBox(100, 100, 100, 100);
            textBox.AddParagraph().AddRun(i.ToString());
        }

        // Create save options.
        var saveOptions = new PptxSaveOptions();
        saveOptions.ProgressChanged += (eventSender, args) =>
        {
            Console.WriteLine($"Progress changed - {args.ProgressPercentage}%");
        };

        // Save document.
        presentation.Save("presentation.pptx", saveOptions);
    }
}
Imports GemBox.Presentation
Imports System

Module Program

    Sub Main()

        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Console.WriteLine("Creating presentation")

        ' Create large presentation.
        Dim presentation As New PresentationDocument()
        For i As Integer = 0 To 10000
            Dim slide = presentation.Slides.AddNew()
            Dim textBox = slide.Content.AddTextBox(100, 100, 100, 100)
            textBox.AddParagraph().AddRun(i.ToString())
        Next

        ' Create save options.
        Dim saveOptions = New PptxSaveOptions()
        AddHandler saveOptions.ProgressChanged,
            Sub(eventSender, args)
                Console.WriteLine($"Progress changed - {args.ProgressPercentage}%")
            End Sub

        ' Save presentation.
        presentation.Save("presentation.pptx", saveOptions)

    End Sub

End Module
The progress reported with GemBox.Presentation
Screenshot of the progress reported with GemBox.Presentation

The operations that support progress reporting and canceling are loading of PPTX files and saving of PPTX, PDF, and image files.

As you can see you can track the operations by handling the PptxLoadOptions.ProgressChanged, PptxSaveOptions.ProgressChanged, PdfSaveOptions.ProgressChanged, and ImageSaveOptions.ProgressChanged events.

Progress reporting in WPF

The following example shows how to use Tasks in a WPF application to run the load operation on a new thread and how to use the SynchronizationContext to make changes to the progress bar on the UI thread.

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Progress reporting in WPF" Height="150" Width="300">
    <Grid>
        <ProgressBar HorizontalAlignment="Left" Height="32" Margin="27,73,0,0" VerticalAlignment="Top" Width="200" Name="progressBar"/>
        <Button x:Name="button" Content="Load" HorizontalAlignment="Left" Margin="27,19,0,0" VerticalAlignment="Top" Width="236" Height="36" Click="loadButton_Click"/>
        <Label x:Name="percentageLabel" Content="" HorizontalAlignment="Left" Margin="239,77,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.867,0.59"/>
    </Grid>
</Window>
using GemBox.Presentation;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");
        InitializeComponent();
    }

    private async void loadButton_Click(object sender, RoutedEventArgs e)
    {
        // Capture the current context on the UI thread.
        var context = SynchronizationContext.Current;

        // Create load options.
        var loadOptions = new PptxLoadOptions();
        loadOptions.ProgressChanged += (eventSender, args) =>
        {
            var percentage = args.ProgressPercentage;
            // Invoke on the UI thread.
            context.Post(progressPercentage =>
            {
                // Update UI.
                this.progressBar.Value = (int)progressPercentage;
                this.percentageLabel.Content = progressPercentage.ToString() + "%";
            }, percentage);
        };

        this.percentageLabel.Content = "0%";
        // Use tasks to run the load operation in a new thread.
        var file = await Task.Run(() => PresentationDocument.Load("%#LargePresentation.pptx%", loadOptions));
    }
}
Imports GemBox.Presentation
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows

Class MainWindow

    Public Sub New()
        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")
        InitializeComponent()
    End Sub

    Private Async Sub loadButton_Click(sender As Object, e As RoutedEventArgs)
        ' Capture the current context on the UI thread.
        Dim context = SynchronizationContext.Current

        ' Create load options.
        Dim loadOptions = New PptxLoadOptions()
        AddHandler loadOptions.ProgressChanged,
            Sub(eventSender, args)
                Dim percentage = args.ProgressPercentage
                ' Invoke on the UI thread.
                context.Post(
                    Sub(progressPercentage)
                        ' Update UI.
                        Me.progressBar.Value = CType(progressPercentage, Integer)
                        Me.percentageLabel.Content = progressPercentage.ToString() & "%"
                    End Sub, percentage)
            End Sub

        Me.percentageLabel.Content = "0%"
        ' Use tasks to run the load operation in a new thread.
        Await Task.Run(
            Sub()
                PresentationDocument.Load("%#LargePresentation.pptx%", loadOptions)
            End Sub)
    End Sub

End Class
The progress reported in WPF with GemBox.Presentation
Screenshot of the progress reported in WPF with GemBox.Presentation

The ProgressChanged event is fired on the same thread that started the operation. Therefore, if the operation starts in the UI thread of a WPF application, the thread will be blocked. Because of that, the application won't show the changes made as a response to the fired event.

Progress reporting in Windows Forms

Similarly to WPF, to show the progress of an operation in the UI, it is necessary to run the process on a separate thread and report the changes on the UI thread.

The following example shows how to do that in a Windows Forms application.

using GemBox.Presentation;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

public partial class MainForm : Form
{
    public MainForm()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");
        InitializeComponent();
    }

    private async void loadButton_Click(object sender, EventArgs e)
    {
        // Capture the current context on the UI thread.
        var context = SynchronizationContext.Current;

        // Create load options.
        var loadOptions = new PptxLoadOptions();
        loadOptions.ProgressChanged += (eventSender, args) =>
        {
            var percentage = args.ProgressPercentage;
            // Invoke on the UI thread.
            context.Post(progressPercentage =>
            {
                // Update UI.
                this.progressBar.Value = (int)progressPercentage;
                this.percentageLabel.Text = progressPercentage.ToString() + "%";
            }, percentage);
        };

        this.percentageLabel.Text = "0%";
        // Use tasks to run the load operation in a new thread.
        var file = await Task.Run(() => PresentationDocument.Load("%#LargePresentation.pptx%", loadOptions));
    }
}
Imports GemBox.Presentation
Imports System
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows.Forms

Public Class MainForm

    Public Sub New()
        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")
        InitializeComponent()
    End Sub

    Private Async Sub LoadButton_Click(sender As Object, e As EventArgs) Handles LoadButton.Click
        ' Capture the current context on the UI thread.
        Dim context = SynchronizationContext.Current

        ' Create load options.
        Dim loadOptions = New PptxLoadOptions()
        AddHandler loadOptions.ProgressChanged,
            Sub(eventSender, args)
                Dim percentage = args.ProgressPercentage
                ' Invoke on the UI thread.
                context.Post(
                    Sub(progressPercentage)
                        ' Update UI.
                        Me.ProgressBar.Value = CType(progressPercentage, Integer)
                        Me.PercentageLabel.Text = progressPercentage.ToString() & "%"
                    End Sub, percentage)
            End Sub

        Me.PercentageLabel.Text = "0%"
        ' Use tasks to run the load operation in a new thread.
        Await Task.Run(
            Sub()
                PresentationDocument.Load("%#LargePresentation.pptx%", loadOptions)
            End Sub)
    End Sub

End Class
The progress reported in Windows Forms with GemBox.Presentation
Screenshot of the progress reported in Windows Forms with GemBox.Presentation

Cancellation

The following example shows how to cancel the saving of a presentation in a console application after a specific time.

using GemBox.Presentation;
using System;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        // Create presentation.
        var presentation = new PresentationDocument();
        for (var i = 0; i < 10000; i++)
        {
            var slide = presentation.Slides.AddNew();
            var textBox = slide.Content.AddTextBox(100, 100, 100, 100);
            textBox.AddParagraph().AddRun(i.ToString());
        }

        var stopwatch = new Stopwatch();
        stopwatch.Start();

        // Create save options.
        var saveOptions = new PptxSaveOptions();
        saveOptions.ProgressChanged += (sender, args) =>
        {
            // Cancel operation after five seconds.
            if (stopwatch.Elapsed.Seconds >= 5)
                args.CancelOperation();
        };

        try
        {
            presentation.Save("Cancellation.pptx", saveOptions);
            Console.WriteLine("Operation fully finished");
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Operation was cancelled");
        }
    }
}
Imports GemBox.Presentation
Imports System
Imports System.Diagnostics

Module Program

    Sub Main()

        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        ' Create document.
        Dim presentation As New PresentationDocument()
        For i As Integer = 0 To 10000
            Dim slide = presentation.Slides.AddNew()
            Dim textBox = slide.Content.AddTextBox(100, 100, 100, 100)
            textBox.AddParagraph().AddRun(i.ToString())
        Next

        Dim stopwatch = New Stopwatch()
        stopwatch.Start()

        ' Create save options.
        Dim saveOptions = New PptxSaveOptions()
        AddHandler saveOptions.ProgressChanged,
            Sub(eventSender, args)
                ' Cancel operation after five seconds.
                If stopwatch.Elapsed.Seconds >= 5 Then
                    args.CancelOperation()
                End If
            End Sub

        Try
            presentation.Save("Cancellation.pptx", saveOptions)
            Console.WriteLine("Operation fully finished")
        Catch ex As OperationCanceledException
            Console.WriteLine("Operation was cancelled")
        End Try

    End Sub

End Module

Cancellation in WPF

The example below shows how to implement a button in WPF that cancels the load operation.

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Cancellation in WPF" Height="200" Width="350">
    <Grid>
        <Button x:Name="loadButton" Content="Start Loading" HorizontalAlignment="Left" Margin="57,31,0,0" VerticalAlignment="Top" Width="228" Height="31" Click="loadButton_Click" />
        <Button x:Name="cancelButton" Content="Cancel" HorizontalAlignment="Left" Margin="57,111,0,0" VerticalAlignment="Top" Width="228" Height="32" Click="cancelButton_Click" />
        <ProgressBar HorizontalAlignment="Left" Height="25" Margin="57,73,0,0" VerticalAlignment="Top" Width="228" Name="progressBar" />
    </Grid>
</Window>
using GemBox.Presentation;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

public partial class MainWindow : Window
{
    private volatile bool cancellationRequested;

    public MainWindow()
    {
        // If using the Professional version, put your serial key below
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");
        InitializeComponent();
    }

    private async void loadButton_Click(object sender, RoutedEventArgs e)
    {
        // Capture the current context on the UI thread.
        var context = SynchronizationContext.Current;

        var loadOptions = new PptxLoadOptions();
        loadOptions.ProgressChanged += (eventSender, args) =>
        {
            // Show progress.
            context.Post(progressPercentage => this.progressBar.Value = (int)progressPercentage, args.ProgressPercentage);

            // Cancel if requested.
            if (this.cancellationRequested)
                args.CancelOperation();
        };

        try
        {
            var file = await Task.Run(() => PresentationDocument.Load("%#LargePresentation.pptx%", loadOptions));
        }
        catch (OperationCanceledException)
        {
            // Operation cancelled.
        }
    }

    private void cancelButton_Click(object sender, RoutedEventArgs e)
    {
        this.cancellationRequested = true;
    }
}
Imports GemBox.Presentation
Imports System
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows

Class MainWindow

    Private Property cancellationRequested As Boolean

    Public Sub New()
        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")
        InitializeComponent()
    End Sub

    Private Async Sub loadButton_Click(sender As Object, e As RoutedEventArgs) Handles loadButton.Click
        ' Capture the current context on the UI thread.
        Dim context = SynchronizationContext.Current

        ' Create load options.
        Dim loadOptions = New PptxLoadOptions()
        AddHandler loadOptions.ProgressChanged,
            Sub(eventSender, args)
                ' Show progress.
                context.Post(
                    Sub(progressPercentage)
                        Me.progressBar.Value = CType(progressPercentage, Integer)
                    End Sub, args.ProgressPercentage)

                ' Cancel if requested.
                If Me.cancellationRequested Then
                    args.CancelOperation()
                End If
            End Sub

        Try
            Dim file = Await Threading.Tasks.Task.Run(
                Function() As PresentationDocument
                    Return PresentationDocument.Load("%#LargePresentation.pptx%", loadOptions)
                End Function)
        Catch ex As OperationCanceledException
            ' Operation cancelled.
        End Try
    End Sub

    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs) Handles cancelButton.Click
        Me.cancellationRequested = True
    End Sub

End Class
Cancellation in WPF with GemBox.Presentation
Screenshot of cancelled operation in WPF with GemBox.Presentation

See also


Next steps

GemBox.Presentation is a .NET component that enables you to read, write, edit, convert, and print presentation files from your .NET applications using one simple API.

Download Buy