C# background worker not triggering dowork event on any pc besides my own

Brandonm picture Brandonm · Nov 24, 2011 · Viewed 10k times · Source

I'm having a really weird issue with a background worker in one of my applications. I recently overhauled it slightly with some GUI fixes but now when someone on another PC runs the .exe or installs my OneClick deployment the background worker doesn't enter the dowork event. The logic has not changed between the 2 releases. I've done a compare and besides adding more error logging nothing has changed.

I've gone as far as to include message boxes and breakpoints in the dowork event but it never enters it anywhere besides on my own PC. Even when i remote debug it doesnt enter the DoWork event

Any suggestions?

Button click even calls the runworkerasync event

private void ScanButton_Click_1(object sender, RoutedEventArgs e)
    {

        Scan = new BackgroundWorker();
        Scan.WorkerReportsProgress = true;
        Scan.DoWork += new DoWorkEventHandler(Scan_DoWork);
        Scan.ProgressChanged += new ProgressChangedEventHandler(Scan_ProgressChanged);
        Scan.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Scan_RunWorkerCompleted);
        Scan.RunWorkerAsync();
    }

Below is the code that runs the DoWork event. Ive removed the other functions it does for simplicity. All it does is run a function that returns a string and places it inside of the list called scanresults.

private BackgroundWorker Scan;

    public void Scan_DoWork(object sender, DoWorkEventArgs e)
    {

        System.Windows.Forms.MessageBox.Show("Inside the DoWork");

        BackgroundWorker bw = sender as BackgroundWorker;

        float percentageDone = 0.0F;

        ScanResults = new List<string>();

        try
        {

            System.Windows.Forms.MessageBox.Show("Doing first scan check");

            ScanResults.Add(Functions.LocalComputerName());
            percentageDone = ((1 / 1f) * 100f);
            bw.ReportProgress((int)percentageDone);

        }
        catch (Exception ex)
        {
            System.Windows.MessageBox.Show(ex.Message, "Error Encountered", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }
    }


public void Scan_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        try
        {
            if (ScanResults.Count == 0)
            {
                System.Windows.Forms.MessageBox.Show("Empty");
                return;
            }
            MachineNameBox.Text = ScanResults[0];
        }
        catch (Exception ex)
        {
            System.Windows.MessageBox.Show(ex.Message, "Error Encountered", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }
    }

It completely ignores the dowork event and enters the runworkercomplete event and passes a error for the index obviously because the list hasnt been filled as the function do that has been skipped. Again this works perfectly on my PC but not on others no matter how i release it to them.

Thanks for any assistance

Answer

Jay Riggs picture Jay Riggs · Nov 24, 2011

My guess is that your DoWork is throwing an exception and so your RunWorkerCompleted is called.

Note that exceptions thrown in a BGW's DoWork method will not be caught in a try...catch in RunWorkerCompleted; instead, the pattern is to check if the Error property in RunWorkerCompleted's RunWorkerCompletedEventArgs parameter is not null. If this is not null, you have an exception.

You might rework your RunWorkerCompleted code like this:

public void Scan_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
    if (e.Error != null) {
        // You have an exception, which you can examine through the e.Error property.
    } else {
        // No exception in DoWork.
        try {
            if (ScanResults.Count == 0) {
                System.Windows.Forms.MessageBox.Show("Empty");
                return;
            }
            MachineNameBox.Text = ScanResults[0];
        } catch (Exception ex) {
            System.Windows.MessageBox.Show(ex.Message, "Error Encountered", MessageBoxButton.OK, MessageBoxImage.Exclamation);
        }
    }
}

See BackgroundWorker.RunWorkerCompleted Event for more info and a better example than mine.