Multithreading in Aspose.Slides
Introduction
While parallel work with presentations is possible (besides parsing/loading/cloning) and everything goes well (most times), there is a small chance you might get incorrect results when you use the library in multiple threads.
We strongly recommend that you do not use a single Presentation instance in a multi-threading environment because it might result in unpredictable errors or failures that are not easily detected.
It is not safe to load, save, and/or clone an instance of a Presentation class in multiple threads. Such operations are not supported. If you need to perform such tasks, you have to parallel the operations using several single-threaded processes—and each of these processes should use its own presentation instance.
Convert Presentation Slides to Images in Parallel
Let’s say we want to convert all the slides from a PowerPoint presentation to PNG images in parallel. Since it is unsafe to use a single Presentation
instance in multiple threads, we split the presentation slides into separate presentations and convert the slides to images in parallel, using each presentation in a separate thread. The following code example shows how to do this.
String inputFilePath = "sample.pptx";
String outputFilePathTemplate = "slide_%d.png";
final float imageScale = 2;
Presentation presentation = new Presentation(inputFilePath);
int slideCount = presentation.getSlides().size();
Dimension2D slideSize = presentation.getSlideSize().getSize();
float slideWidth = (float) slideSize.getWidth();
float slideHeight = (float) slideSize.getHeight();
List<CompletableFuture<Void>> conversionTasks = new ArrayList<>(slideCount);
for (int slideIndex = 0; slideIndex < slideCount; slideIndex++) {
// Extract slide i into a separate presentation.
Presentation slidePresentation = new Presentation();
slidePresentation.getSlideSize().setSize(slideWidth, slideHeight, SlideSizeScaleType.DoNotScale);
slidePresentation.getSlides().removeAt(0);
slidePresentation.getSlides().addClone(presentation.getSlides().get_Item(slideIndex));
// Convert the slide to an image in a separate task.
final int slideNumber = slideIndex + 1;
conversionTasks.add(CompletableFuture.runAsync(() -> {
IImage image = null;
try {
ISlide slide = slidePresentation.getSlides().get_Item(0);
image = slide.getImage(imageScale, imageScale);
String imageFilePath = String.format(outputFilePathTemplate, slideNumber);
image.save(imageFilePath, ImageFormat.Png);
} finally {
if (image != null) image.dispose();
slidePresentation.dispose();
}
}));
}
// Wait for all tasks to complete.
CompletableFuture.allOf(conversionTasks.toArray(new CompletableFuture[0])).join();
presentation.dispose();