Background Work in Uno Platform Applications

Background work is a common requirement for many applications, especially those that need to perform some long-running or intensive operations without blocking the user interface.

For example, you might want to download data from a remote server, process images, or sync some files in the background. Background work can also help improve the responsiveness and performance of an application and the user experience. However, implementing background work can be challenging, especially when it comes to updating the UI with the progress or results of the task since the UI thread and the background thread are different and cannot access each other’s resources directly.

In this blog post, I will show you how to implement background work in Uno Platform and run it on Windows, iOS, and Android. We will use a progress bar and some text blocks as the UI elements to be updated by the background task.

Getting Started

The first step is to create a new Uno Platform project in Visual Studio. You can follow the official documentation to set up your development environment and create a new project.

Once the project is created, we will add a Progress Bar control and other UI elements we might want to update as the background worker executes the work.

				
					<StackPanel Orientation="Horizontal"
				Spacing="15">
		<Button x:Name="StartWorkerButton"
				Content="Start"
				HorizontalAlignment="Left"
				Click="StartWorkerButton_Click" />
		<Button x:Name="CancelWorkerButton"
				Content="Cancel"
				HorizontalAlignment="Right"
				Click="CancelWorkerButton_Click" />
</StackPanel>

<ProgressBar x:Name="ProgressBarControl"
			 Value="0"
			 IsIndeterminate="False"
			 Width="200"
			 Maximum="100" />
<TextBlock x:Name="ProgressLabel" />
<TextBlock x:Name="StatusLabel" />
				
			

The StartWorkerButton will start the background work when clicked, and the CancelWorkerButton will cancel an already executed work. The ProgressBar control has a value property that indicates the current progress of the operation, from 0 to 100. We will update this property from the background task. We will also update Text blocks to give visual indications of what is happening behind the scenes.

Code Behind Implementation of BackgroundWorker

Add a BackgroundWorker field named backgroundWorker to the MainPage.xaml.cs file. A BackgroundWorker is a class in the namespace System.ComponentModel that provides a simple way to run a task on a separate thread and report its progress or completion to the UI thread. The backgroundWorker field will hold the instance of the BackgroundWorker class that we will use for the background work.

For example:
				
					// Create a BackgroundWorker instance
private BackgroundWorker worker = new BackgroundWorker();

// A DispatcherQueue instance that will execute tasks serially on the current thread.
private DispatcherQueue dispatcherQueue => DispatcherQueue.GetForCurrentThread();
				
			

You can subscribe to events such as DoWork, ProgressChanged, and RunWorkerCompleted. These events will allow you to execute the task, report its progress, and handle its completion.

For example:
				
					public MainPage()
{
    this.InitializeComponent();
    // Set the properties of the BackgroundWorker
    worker.WorkerReportsProgress = true;
    worker.WorkerSupportsCancellation = true;

    // Handle the events of the BackgroundWorker
    worker.DoWork += Worker_DoWork; ;
    worker.ProgressChanged += Worker_ProgressChanged;
    worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
}
				
			

Implement the event handlers for the BackgroundWorker events. In the DoWork event handler, you can write the logic for the task you want to run on a separate thread. In this example, we will simulate a file download using a loop that increments a counter and sleeps for 100 milliseconds on each iteration. You can use the ReportProgress method of the BackgroundWorker to report the progress of the task as a percentage.

				
					private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
    // Perform the task on a separate thread
    for (int i = 0; i <= 100; i++)
    {
        // Check for cancellation
        if (worker.CancellationPending)
        {
        e.Cancel = true;
        break;
        }
        // Simulate some work
        System.Threading.Thread.Sleep(100);
    
        // Report progress
        worker.ReportProgress(i);
    }
}
				
			

In the ProgressChanged event handler, you can update the UI with the progress value reported by the task. In this example, we will update the Value property of the Progress Bar control and the Textblock named ProgressLabel with the progress value.

				
					private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
  // Update the UI with the progress on the main thread
  DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
  {
    ProgressBarControl.Value = e.ProgressPercentage;
    ProgressLabel.Text = $"{e.ProgressPercentage}%";
  });
}
				
			

In the RunWorkerCompleted event handler, you can perform any actions that need to be done after the task is completed.

				
					private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  // Handle the completion or cancellation of the task on the main thread
  DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () =>
  {
    if (e.Cancelled)
    {
      StatusLabel.Text = "Cancelled";
    }
    else if (e.Error != null)
    {
      StatusLabel.Text = "Error: " + e.Error.Message;
    }
    else
    {
      StatusLabel.Text = "Done";
    }
  });
}
				
			

To upgrade to the latest release of Uno Platform, please update your packages to 4.9 via your Visual Studio NuGet package manager! If you are new to Uno Platform, following our official getting started guide is the best way to get started. (5 min to complete)

Congratulations! You have successfully implemented background work using BackgroundWorker in Uno Platform. 

Next Steps

To upgrade to the latest release of Uno Platform, please update your packages to 4.9 via your Visual Studio NuGet package manager! If you are new to Uno Platform, following our official getting started guide is the best way to get started. (5 min to complete)

Tags: