.NET HELP

C# Interlocked (How it Works for Developers)

Chipego
Chipego Kalinda
April 3, 2025
Share:

When working with multi-threaded applications, ensuring thread safety becomes a crucial factor in preventing race conditions and data corruption. In the world of PDF processing with IronPDF, this issue is no different. Whether you’re generating, manipulating, or combining PDFs, running these tasks concurrently can lead to unexpected results if proper synchronization is not maintained. This is where C#'s Interlocked class comes into play, providing a simple and efficient way to ensure thread-safe operations in a multi-threaded environment.

What is the C# Interlocked Class?

In C#, the Interlocked class provides atomic operations for variables shared by multiple threads. This ensures that one thread’s actions won’t be interfered with by another, which is essential when you need to guarantee that operations are performed in a controlled and consistent manner. On the other hand, IronPDF is a powerful library that allows .NET developers to create, edit, and manipulate PDFs.

When you combine the two—Interlocked for thread safety and IronPDF for PDF operations—you get a potent solution for handling PDF tasks in concurrent programming. But how does this work, and why should you care? Let’s dive deeper into the role of Interlocked in IronPDF processing.

IronPDF: The All-In-One C# PDF Library

C# Interlocked (How it Works for Developers): Figure 1 Add from PixabayUpload

or drag and drop an image here

Add image alt text

IronPDF is a versatile and feature-rich library designed to work seamlessly with C# and .NET applications for PDF generation and manipulation. Its simplicity and performance make it a popular choice for developers who need to automate PDF tasks. Below are some key features of IronPDF:

  • HTML to PDF Conversion: IronPDF allows you to convert HTML content into high-quality PDFs. This is particularly useful for creating reports, invoices, and any content that is rendered in HTML.
  • PDF Editing and Manipulation: You can manipulate existing PDF documents by merging, splitting, or extracting pages. Additionally, IronPDF allows you to modify content within PDFs, such as adding text, images, or annotations.
  • PDF Forms and Fields: IronPDF supports working with PDF forms, including filling form fields programmatically. This is ideal for automating the process of generating documents like surveys, applications, and contracts.
  • Digital Signatures: It provides features to sign PDFs digitally with a secure signature, which is a vital feature for industries requiring secure document transactions, such as legal and financial sectors.

By leveraging these features, IronPDF helps developers create, manage, and automate PDF workflows efficiently, all while ensuring high-quality results. Whether you're working with dynamic HTML content or manipulating existing documents, IronPDF provides the tools needed to streamline your PDF-related tasks.

Why Use Interlocked in IronPDF Processing?

Thread Safety and Concurrency

In multi-threaded applications, multiple threads can attempt to access and modify shared data at the same time. Without proper synchronization, this could lead to issues like race conditions, where two threads try to update the same data simultaneously. This can cause unpredictable results and errors that are difficult to debug.

The Interlocked class ensures that these concurrent operations are handled atomically. In other words, when you use Interlocked to modify an object value, the change happens as a single, uninterruptible operation, which eliminates the risk of a race condition.

In the context of IronPDF, many PDF processing tasks—such as adding pages, editing content, or generating PDFs from multiple sources—are ideal candidates for parallel processing. Without synchronization, running these operations concurrently could result in corrupted PDF files or errors during processing. Using Interlocked ensures that these operations remain safe, even in a multi-threaded environment.

Using Interlocked with Different Data Types

When dealing with variables of different data types, Interlocked can be used to safely manage concurrent updates. Let’s explore some of the data types you might encounter:

  • Float value: The Interlocked.CompareExchange method can be used with floating-point values when a reference type is required for the operation.
  • Original value: When performing updates, it’s important to work with the original value before making changes to ensure consistency in thread operations.
  • Public static class: You can create a public static class to encapsulate your Interlocked operations, making your code more modular and easier to maintain.
  • Double value: Interlocked does not directly support double values, because double is not an integral type, and atomic operations are optimized for integers. If you need atomic operations on double values, you can work around it by using long values and manually converting between double and long value.
public static class ThreadSafeOperations
{
    private static int counter = 0;
    public static void IncrementCounter()
    {
        // Safely increment the counter using Interlocked
        Interlocked.Increment(ref counter);
    }
}
public static class ThreadSafeOperations
{
    private static int counter = 0;
    public static void IncrementCounter()
    {
        // Safely increment the counter using Interlocked
        Interlocked.Increment(ref counter);
    }
}

When to Use Interlocked with IronPDF

You should use Interlocked in any scenario where multiple threads are working with shared resources. Examples include:

  • Tracking page numbers in PDF generation.
  • Managing counters or lists that are accessed and modified by multiple threads.

By using Interlocked for these operations, you ensure that updates are thread-safe, preventing conflicts and ensuring data integrity.

Implementing Interlocked with IronPDF

Basic Usage of Interlocked in C#

The Interlocked class offers several methods to perform atomic operations on variables, such as:

  • Add: Adds two integers and stores the result in a variable.
  • CompareExchange: Compares two values for equality and, if they are equal, replaces one of the values.
  • Increment: Increases an int value by one and returns the new value.
  • Decrement: Decreases an int value by one and returns the new value.

For example, if you need to increment a shared counter safely in a multi-threaded environment, use Interlocked.Increment:

int counter = 0;
Interlocked.Increment(ref counter);
int counter = 0;
Interlocked.Increment(ref counter);

This guarantees that the counter is safely incremented, even when multiple threads are modifying it simultaneously.

Thread-Safe PDF Generation with IronPDF and C# Interlocked

Let’s take a look at a practical example of using Interlocked with IronPDF in a multi-threaded context. Suppose you are generating PDF files in parallel threads and need each thread to have a unique identifier or page number.

Here’s how you can implement this:

using IronPdf;
using System;
using System.Threading;
class Program
{
    static int pageCount = 0;
    static readonly object lockObject = new object(); // Object for locking
    static void Main()
    {
        var threads = new Thread[5];
        List<PdfDocument> pdfList = new List<PdfDocument>();
        // Create threads for parallel PDF generation
        for (int i = 0; i < threads.Length; i++)
        {
            threads[i] = new Thread(() => GeneratePdf(pdfList));
            threads[i].Start();
        }
        // Wait for all threads to complete
        foreach (var thread in threads)
        {
            thread.Join();
        }
        // Merge all the generated PDFs
        PdfDocument finalPdf = pdfList[0]; // Start with the first document
        // Merge remaining PDFs into finalPdf
        for (int i = 1; i < pdfList.Count; i++)
        {
            finalPdf = PdfDocument.Merge(finalPdf, pdfList[i]);
        }
        // Save the merged PDF
        finalPdf.SaveAs("MergedGeneratedPDF.pdf");
        Console.WriteLine("All PDFs merged and saved successfully.");
    }
    static void GeneratePdf(List<PdfDocument> pdfList)
    {
        // Use ChromePdfRenderer instead of HtmlToPdf
        ChromePdfRenderer renderer = new ChromePdfRenderer();
        // Use Interlocked to ensure unique page number per thread and using a "ref object" to reference the pageCount object 
        int pageNum = Interlocked.Increment(ref pageCount);
        // Generate a PDF page using ChromePdfRenderer
        var pdfPage = renderer.RenderHtmlAsPdf($"Page {pageNum} generated by thread {Thread.CurrentThread.ManagedThreadId}");
        // Add generated PDF page to the list (thread-safe)
        lock (lockObject) // Ensure thread-safety when adding to shared list
        {
            pdfList.Add(pdfPage);
        }
        string fileName = $"GeneratedPDF_{pageNum}.pdf";
        pdfPage.SaveAs(fileName);
        Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} generated: {fileName}");
    }
}
using IronPdf;
using System;
using System.Threading;
class Program
{
    static int pageCount = 0;
    static readonly object lockObject = new object(); // Object for locking
    static void Main()
    {
        var threads = new Thread[5];
        List<PdfDocument> pdfList = new List<PdfDocument>();
        // Create threads for parallel PDF generation
        for (int i = 0; i < threads.Length; i++)
        {
            threads[i] = new Thread(() => GeneratePdf(pdfList));
            threads[i].Start();
        }
        // Wait for all threads to complete
        foreach (var thread in threads)
        {
            thread.Join();
        }
        // Merge all the generated PDFs
        PdfDocument finalPdf = pdfList[0]; // Start with the first document
        // Merge remaining PDFs into finalPdf
        for (int i = 1; i < pdfList.Count; i++)
        {
            finalPdf = PdfDocument.Merge(finalPdf, pdfList[i]);
        }
        // Save the merged PDF
        finalPdf.SaveAs("MergedGeneratedPDF.pdf");
        Console.WriteLine("All PDFs merged and saved successfully.");
    }
    static void GeneratePdf(List<PdfDocument> pdfList)
    {
        // Use ChromePdfRenderer instead of HtmlToPdf
        ChromePdfRenderer renderer = new ChromePdfRenderer();
        // Use Interlocked to ensure unique page number per thread and using a "ref object" to reference the pageCount object 
        int pageNum = Interlocked.Increment(ref pageCount);
        // Generate a PDF page using ChromePdfRenderer
        var pdfPage = renderer.RenderHtmlAsPdf($"Page {pageNum} generated by thread {Thread.CurrentThread.ManagedThreadId}");
        // Add generated PDF page to the list (thread-safe)
        lock (lockObject) // Ensure thread-safety when adding to shared list
        {
            pdfList.Add(pdfPage);
        }
        string fileName = $"GeneratedPDF_{pageNum}.pdf";
        pdfPage.SaveAs(fileName);
        Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} generated: {fileName}");
    }
}

Code Explanation

This C# program generates multiple PDFs in parallel using threads, then merges them into a single PDF using IronPDF.

  1. Multithreading: 5 threads are created to generate PDFs concurrently. Each thread gets a unique page number using Interlocked.Increment.
  2. Thread-Safety: Access to the shared pdfList is synchronized with a lock statement to prevent race conditions when adding PDFs to the list.
  3. Merging PDFs: After all threads finish, the PDFs in pdfList are merged sequentially using PdfDocument.Merge, and the final PDF is saved.
  4. Synchronization: The main thread waits for all threads to complete using thread.Join() before proceeding with the merge.

Console Output

C# Interlocked (How it Works for Developers): Figure 2 - Console output for thread-safe PDF generation with C# Interlocked Add from PixabayUpload

or drag and drop an image here

Clear alt text

PDF Output

C# Interlocked (How it Works for Developers): Figure 3 - PDF output for thread-safe PDF generation with C# Interlocked Add from PixabayUpload

or drag and drop an image here

Clear alt text

Why This is Thread-Safe

  • Thread-Safe List Modification: Using lock ensures that the modification of the shared pdfList is safe, preventing multiple threads from adding to the list simultaneously and causing race conditions.
  • No Need for Asynchronous Code: The code doesn't require async/await because the operations are sequential and don't involve long-running I/O or network calls. The main concern here is ensuring that access to shared data (the list) is properly synchronized.

Error Handling and Performance Considerations

When working with multi-threaded code, error handling and performance optimization are essential.

  • Error Handling: Although Interlocked ensures thread safety, you still need to manage potential errors in your PDF generation logic. You can use try-catch blocks to handle exceptions gracefully:
try
{
    finalPdf.SaveAs(fileName);
}
catch (Exception ex)
{
    Console.WriteLine($"Error generating PDF: {ex.Message}");
}
try
{
    finalPdf.SaveAs(fileName);
}
catch (Exception ex)
{
    Console.WriteLine($"Error generating PDF: {ex.Message}");
}
  • Performance Considerations: While Interlocked is optimized for atomic operations, excessive synchronization can introduce overhead. If you are handling a high volume of concurrent operations, you should minimize synchronization to the most critical shared variables to reduce contention.

Conclusion

Thread safety is crucial in multi-threaded applications, especially when dealing with shared resources like counters or lists. When using IronPDF for PDF creation or manipulation, integrating Interlocked ensures that operations remain thread-safe and reliable.

By using Interlocked in conjunction with IronPDF, .NET developers can efficiently scale their PDF processing workflows while maintaining the integrity of the data. Whether you’re generating reports, merging documents, or performing complex PDF manipulations in parallel, Interlocked helps maintain consistency and avoid race conditions.

With these best practices, you can take full advantage of IronPDF’s capabilities and ensure that your multi-threaded PDF workflows are efficient and robust. Ready to start integrating IronPDF today and experience its powerful PDF creation and manipulation features firsthand!

Chipego
Software Engineer
Chipego has a natural skill for listening that helps him to comprehend customer issues, and offer intelligent solutions. He joined the Iron Software team in 2023, after studying a Bachelor of Science in Information Technology. IronPDF and IronOCR are the two products Chipego has been focusing on, but his knowledge of all products is growing daily, as he finds new ways to support customers. He enjoys how collaborative life is at Iron Software, with team members from across the company bringing their varied experience to contribute to effective, innovative solutions. When Chipego is away from his desk, he can often be found enjoying a good book or playing football.
NEXT >
C# String Methods (How it Works for Developers)