How to Use Async and Multithread

The terms Async and Multithreading operations are often confused. Both methods aim to enhance program performance and efficiency by optimizing system resource utilization and reducing runtime. However, they differ in approach, mechanisms, and intended use cases. IronBarcode supports both approaches. This article explores the differences between them and how to implement them using IronBarcode.


Get started with IronBarcode

Start using IronBarcode in your project today with a free trial.

First Step:
green arrow pointer

Read Barcodes Asynchronously Example

Let's begin by understanding what asynchronous reading is and how it benefits users. Asynchronous reading enables long or blocking operations to proceed without blocking the main thread's execution. In C#, users can utilize the async and await keywords with methods supporting asynchronous features. This will not create additional threads, but instead, release the current thread. While the main thread is still necessary to initiate and manage tasks, it doesn't need to be exclusively devoted to a single task. The main thread is summoned when the asynchronous method requires its involvement, freeing it to handle other tasks when not needed—such as I/O-bound tasks like reading/writing files or making network requests.

Let's consider barcode reading as an example. In this scenario, the steps involved would be:

  • Reading the file
  • Applying reading options
  • Decoding the barcode

During the "Reading the file" step, the main task can be released.

Use the ReadAsync and ReadPdfAsync methods to read barcodes asynchronously for images and PDF documents, respectively.

:path=/static-assets/barcode/content-code-examples/how-to/async-multithread-async.cs
using IronBarCode;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

// Entry point for the application
MainAsync().GetAwaiter().GetResult();

/// <summary>
/// This method processes a list of image file paths to read barcodes.
/// It is an asynchronous method that leverages the IronBarCode library to read barcodes from images.
/// </summary>
/// <returns>A Task representing the asynchronous operation.</returns>
async Task MainAsync()
{
    // List of image file paths to process
    List<string> imagePaths = new List<string> { "image1.png", "image2.png" };

    // Configure barcode reading options to expect multiple barcodes
    BarcodeReaderOptions options = new BarcodeReaderOptions
    {
        ExpectMultipleBarcodes = true
    };

    try
    {
        // Read barcodes asynchronously from the images
        BarcodeResults asyncResult = await BarcodeReader.ReadAsync(imagePaths, options);

        // Iterate over each detected barcode and print its details to the console
        foreach (var result in asyncResult)
        {
            Console.WriteLine(result.ToString());
        }
    }
    catch (Exception ex)
    {
        // Handle any exceptions that occur during barcode reading
        Console.WriteLine($"An error occurred: {ex.Message}");
    }
}
Imports IronBarCode
Imports System
Imports System.Collections.Generic
Imports System.Threading.Tasks

' Entry point for the application
MainAsync().GetAwaiter().GetResult()

''' <summary>
''' This method processes a list of image file paths to read barcodes.
''' It is an asynchronous method that leverages the IronBarCode library to read barcodes from images.
''' </summary>
''' <returns>A Task representing the asynchronous operation.</returns>
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'async Task MainAsync()
'{
'	' List of image file paths to process
'	List<string> imagePaths = New List<string> { "image1.png", "image2.png" };
'
'	' Configure barcode reading options to expect multiple barcodes
'	BarcodeReaderOptions options = New BarcodeReaderOptions { ExpectMultipleBarcodes = True };
'
'	try
'	{
'		' Read barcodes asynchronously from the images
'		BarcodeResults asyncResult = await BarcodeReader.ReadAsync(imagePaths, options);
'
'		' Iterate over each detected barcode and print its details to the console
'		foreach (var result in asyncResult)
'		{
'			Console.WriteLine(result.ToString());
'		}
'	}
'	catch (Exception ex)
'	{
'		' Handle any exceptions that occur during barcode reading
'		Console.WriteLine(string.Format("An error occurred: {0}", ex.Message));
'	}
'}
$vbLabelText   $csharpLabel

From the code snippet above, we have instantiated a List of image paths to be read asynchronously by IronBarcode. To read the images, you can use the ReadAsync method from the BarcodeReader class. Users can then specify the imagePaths as well as reading options.

This method for asynchronous operations is also available to read barcodes in PDF documents, known as ReadPdfAsync, which is part of the same class.

Read Barcodes in Multithread Example

Differing from asynchronous operations, multithreading allows a single process to be executed in multiple threads simultaneously. This means that instead of executing a process sequentially in a single thread, multithreading divides tasks among multiple threads, enabling concurrent execution. However, for multithreading to function, a machine must have multiple CPU cores, as these cores are used to independently execute the threads. Similar to asynchronous operations, multithreading aims to enhance the performance and responsiveness of applications.

In IronBarcode, enable multithreading by setting the Multithreaded property and specifying the maximum cores for concurrent execution using MaxParallelThreads in BarcodeReaderOptions. The default value for MaxParallelThreads is 4, which can be adjusted based on the available CPU cores.

Please note
To find available cores: Task Manager -> Performance tab -> Click CPU. 'Cores' field displays count.

:path=/static-assets/barcode/content-code-examples/how-to/async-multithread-multithread.cs
using IronBarCode;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

// The main program class containing the entry point of the application
class Program
{
    // Asynchronous main entry point of the application
    static async Task Main(string[] args)
    {
        // Create a list of image file paths to be scanned for barcodes
        List<string> imagePaths = new List<string> { "test1.jpg", "test2.png" };

        // Configure the barcode reader options
        BarcodeReaderOptions options = new BarcodeReaderOptions()
        {
            Multithreaded = true, // Enable multithreading to enhance processing speed
            MaxParallelThreads = 4, // Limit the maximum parallel threads to 4 for controlled concurrency
            ExpectMultipleBarcodes = true // Specify that the images may contain multiple barcodes
        };

        try
        {
            // Use the BarcodeReader to asynchronously read barcodes from the image paths
            BarcodeResults results = await BarcodeReader.ReadAsync(imagePaths, options);

            // Iterate through each result and print the decoded barcode information
            foreach (var result in results)
            {
                Console.WriteLine(result.ToString()); // Display the result information
            }
        }
        catch (Exception ex)
        {
            // Handle potential exceptions, such as file read errors or processing errors
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }
}
Imports IronBarCode
Imports System
Imports System.Collections.Generic
Imports System.Threading.Tasks

' The main program class containing the entry point of the application
Friend Class Program
	' Asynchronous main entry point of the application
	Shared Async Function Main(ByVal args() As String) As Task
		' Create a list of image file paths to be scanned for barcodes
		Dim imagePaths As New List(Of String) From {"test1.jpg", "test2.png"}

		' Configure the barcode reader options
		Dim options As New BarcodeReaderOptions() With {
			.Multithreaded = True,
			.MaxParallelThreads = 4,
			.ExpectMultipleBarcodes = True
		}

		Try
			' Use the BarcodeReader to asynchronously read barcodes from the image paths
			Dim results As BarcodeResults = Await BarcodeReader.ReadAsync(imagePaths, options)

			' Iterate through each result and print the decoded barcode information
			For Each result In results
				Console.WriteLine(result.ToString()) ' Display the result information
			Next result
		Catch ex As Exception
			' Handle potential exceptions, such as file read errors or processing errors
			Console.WriteLine($"An error occurred: {ex.Message}")
		End Try
	End Function
End Class
$vbLabelText   $csharpLabel

Performance Comparison

Now, let's read the two images below and compare the reading time of normal, asynchronous, and multithread operations.

Sample Image

Image 1
Image 2
Normal ReadAsynchronous ReadMultithreaded Read (4 cores)
01.75 seconds01.67 seconds01.17 seconds

From the comparison table, it's evident that there is a significant increase in performance once asynchronous and multithreaded reading is implemented. However, these two operations serve different purposes and approaches. Therefore, users need to determine which approach better suits the application they are building.

Finally, there might be situations where multiple barcodes are present on a single document. For more information, visit the Read Multiple Barcodes guide.

Frequently Asked Questions

What is the difference between async and multithreading?

Async and multithreading both aim to enhance program performance by optimizing resource utilization. However, async allows operations to proceed without blocking the main thread, while multithreading divides tasks among multiple threads for concurrent execution.

How does IronBarcode support asynchronous barcode reading?

IronBarcode supports asynchronous barcode reading using the `ReadAsync` and `ReadPdfAsync` methods. These methods enable reading barcodes from images and PDFs without blocking the main thread.

How do you enable multithreading in IronBarcode?

In IronBarcode, multithreading is enabled by setting the `Multithreaded` property to true and using the `MaxParallelThreads` property to specify the number of cores for concurrent execution.

What are the benefits of using asynchronous operations?

Asynchronous operations allow long or blocking tasks to proceed without blocking the main thread, which frees the main thread to handle other tasks, improving application responsiveness, especially in I/O-bound operations.

What are the benefits of using multithreading?

Multithreading enhances application performance by allowing tasks to execute concurrently across multiple CPU cores, improving processing speed and efficiency for CPU-bound tasks.

How can I download the IronBarcode library?

You can download the C# library for async and multithread support from the .NET package manager NuGet at https://nuget.org/packages/IronPdf/.

What is the default value for MaxParallelThreads in IronBarcode?

The default value for `MaxParallelThreads` in IronBarcode is 4, but it can be adjusted based on the available CPU cores.

How does the performance of normal, async, and multithreaded reads compare?

In performance comparisons, normal reads take longer than async and multithreaded reads. Async reads are slightly faster, and multithreaded reads, utilizing multiple cores, are the fastest.

Can multithreading be used on all machines?

Multithreading requires a machine with multiple CPU cores, as these cores independently execute the threads for concurrent processing.

Where can I find more information on reading multiple barcodes?

For more information on reading multiple barcodes with IronBarcode, visit the guide at /csharp/barcode/how-to/read-multiple-barcodes/.

Hairil Hasyimi Bin Omar
Hairil Hasyimi Bin Omar
Software Engineer
Like all great engineers, Hairil is an avid learner. He’s refining his knowledge of C#, Python, and Java, using that knowledge to add value to team members across Iron Software. Hairil joined the Iron Software team from Universiti Teknologi MARA in Malaysia, where he graduated with a Bachelor's degree in Chemical and Process Engineering.