Featured Post

Organize and rename photos by EXIF data with PowerShell

This PowerShell script organizes and renames all photos in a selected folder using EXIF data. It will also create thumbnails of the images i...

Tuesday, October 29, 2013

BackgroundWorker Example for C#/WPF

Here is a simple example of how to use a BackgroundWorker to execute long running tasks without freezing the UI. This allows you to use ProgressChanged event handler to change your UI with status messages making for a much friendlier user experience.

In this example I am creating and populating a database which takes a minute or so to complete. With my Simple Elegant Busy Indicator for WPF bound to the BusyIndicator property, it lets the user know the application is busy and not frozen.


private void Execute()
{
    // Set status
    BusyIndicator = true;
    Status = "Creating database, please wait. This may take several minutes...";

    // Create Database background worker
    CreateDatabaseWorker = new BackgroundWorker();
    CreateDatabaseWorker.WorkerReportsProgress = true;
    CreateDatabaseWorker.DoWork += new DoWorkEventHandler(CreateDatabase_DoWork);
    CreateDatabaseWorker.ProgressChanged += new ProgressChangedEventHandler(CreateDatabase_WorkerProgressChanged);
    CreateDatabaseWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CreateDatabase_WorkCompleted);
    CreateDatabaseWorker.RunWorkerAsync();
}

// Note: You cannot modify any UI bound property in the _DoWork method
private void CreateDatabase_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        // Long running methods go here
        CreateDatabaseWorker.ReportProgress(25, "Creating employees...");
        Utilities.PopulateDBModel.CreateInitialEmployees();

        CreateDatabaseWorker.ReportProgress(50, "Creating countries and regions...");
        Utilities.PopulateDBModel.CreateCountries();
    }
    catch (Exception ex)
    {
        // If anything fails we set our result to false
        CreateDatabaseWorker.ReportProgress(100, "Error...");
        e.Result = false;
        return;
    }
    e.Result = true;
}

// This will update our UI while our background worker is... working
private void CreateDatabase_WorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
    if (e.UserState != null)
    {
        ProgressBarValue = e.ProgressPercentage;
        Status = e.UserState.ToString();
    }
}

// Now we can evaluate our results
private void CreateDatabase_WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    BusyIndicator = false;

    if ((bool)e.Result != true)
    {
        ShowFailure = true;
        return;
    }

    ShowSuccess = true;
    Status = "Database created successfully!";
}

No comments:

Post a Comment