Asked  6 Months ago    Answers:  5   Viewed   44 times

In my application I need to perform a series of initialization steps, these take 7-8 seconds to complete during which my UI becomes unresponsive. To resolve this I perform the initialization in a separate thread:

public void Initialization()
{
    Thread initThread = new Thread(new ThreadStart(InitializationThread));
    initThread.Start();
}

public void InitializationThread()
{
    outputMessage("Initializing...");
    //DO INITIALIZATION
    outputMessage("Initialization Complete");
}

I have read a few articles about the BackgroundWorker and how it should allow me to keep my application responsive without ever having to write a thread to perform lengthy tasks but I haven't had any success trying to implement it, could anyone tell how I would do this using the BackgroundWorker?

 Answers

44
  1. Add using
using System.ComponentModel;
  1. Declare Background Worker:
private readonly BackgroundWorker worker = new BackgroundWorker();
  1. Subscribe to events:
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
  1. Implement two methods:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
  // run all background tasks here
}

private void worker_RunWorkerCompleted(object sender, 
                                           RunWorkerCompletedEventArgs e)
{
  //update ui once worker complete his work
}
  1. Run worker async whenever your need.
worker.RunWorkerAsync();
  1. Track progress (optional, but often useful)

    a) subscribe to ProgressChanged event and use ReportProgress(Int32) in DoWork

    b) set worker.WorkerReportsProgress = true; (credits to @zagy)

Tuesday, June 1, 2021
 
IcedAnt
answered 6 Months ago
49

As you haven't shown your full BackgroundWorker code, I can't tell if you have implemented it correctly. As such, all I can do is to show you a simple working example of updating a ProgressBar control:

UserControl XAML:

<UserControl x:Class="WpfApplication1.Views.TestView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="300" Loaded="UserControl_Loaded">
    <ProgressBar x:Name="progressBar" Height="25" Margin="20" Minimum="0" 
        Maximum="50" />
</UserControl>

MainWindow XAML:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Views="clr-namespace:WpfApplication1.Views"
    Title="MainWindow" Height="350" Width="525">
    <Views:TestView />
</Window>

UserControl code behind:

using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1.Views
{
    public partial class TestView : UserControl
    {
        private BackgroundWorker backgroundWorker = new BackgroundWorker();

        public TestView()
        {
            InitializeComponent();
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.ProgressChanged += ProgressChanged;
            backgroundWorker.DoWork += DoWork;
            // not required for this question, but is a helpful event to handle
            backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            backgroundWorker.RunWorkerAsync();
        }

        private void DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i <= 100; i++)
            {
                // Simulate long running work
                Thread.Sleep(100);
                backgroundWorker.ReportProgress(i);
            }
        }

        private void ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // This is called on the UI thread when ReportProgress method is called
            progressBar.Value = e.ProgressPercentage;
        }

        private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // This is called on the UI thread when the DoWork method completes
            // so it's a good place to hide busy indicators, or put clean up code
        }
    }
}
Friday, June 4, 2021
 
brombeer
answered 6 Months ago
95

What seems to be happening here is that WPF is ignoring the Cursor setting on the disabled window. The following workaround seems to work: instead of disabling the window itself, disable the content of the window:

C#:

((UIElement)Content).IsEnabled = false;
Cursor = Cursors.Wait;

// and in RunWorkerCompleted handler:
((UIElement)Content).IsEnabled = true;
Cursor = Cursors.Arrow;

Visual Basic:

DirectCast(Content, UIElement).IsEnabled = False
Cursor = Cursors.Wait

' and in RunWorkerCompleted handler:'
DirectCast(Content, UIElement).IsEnabled = True
Cursor = Cursors.Arrow
Friday, August 6, 2021
 
Mirko
answered 4 Months ago
93

Building on the answer from Renuiz, I would do it this way:

private object lockObj;

private void backgroundWorkerN_RunWorkerCompleted(
    object sender, 
    RunWorkerCompletedEventArgs e)
{
    lock (lockObj)
    {
        y = true;
        if (cb && cr) // if cb and cr flags are true - 
                      // other backgroundWorkers finished work
        {
            someMethodToDoOtherStuff();
        }
    }
}
Tuesday, August 24, 2021
 
Sotirios Delimanolis
answered 3 Months ago
52

When you create mog, you are not defining any parameters, so it is created with default parameters. Here you have a description of each parameter, maybe is just that. Try with 3, 4 5 Gaussians.

This function does not perforn shadow-removal but you have this other function that does. Good luck!

Monday, September 20, 2021
 
daydreamer
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share