Search code examples
c#backgroundworkertargetinvocationexception

TargetInvocationException was unhandled at the end of DoWork Backgroundworker Method


Here's DoWork:

private void uploadWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            uploadWorker.ReportProgress(20);

            int tiffError = 0;

            finalFiles = Directory.GetFiles(AppVars.FinalPolicyImagesFolder);

            foreach (string file in finalFiles)
            {
                if (!file.EndsWith(".tiff"))
                {
                    tiffError = 1;
                    break;
                }
            }

            uploadWorker.ReportProgress(50);

            if (tiffError == 1)
            {
                MessageBox.Show("There are files in this folder that are not .tiff. Please ensure only .tiff files are in this folder.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                if (finalFiles.Length == 0)
                {
                    MessageBox.Show("There are no TIFF files to be uploaded. Please generate files first.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    pbUpload.Value = 0;
                    EnableAllButtons();
                }
                else
                {
                    double count = finalFiles.Length;
                    int current = 0;
                    int pbValue = 0;

                    uploadWorker.ReportProgress(70);

                    foreach (string file in finalFiles)
                    {
                        current = current + 2;

                        if (file.Contains(".tiff") == true)
                        {
                            PolicyNumber = Path.GetFileName(file).Split('_')[0];
                            basePolicyNumber = PolicyNumber.Remove(PolicyNumber.Length - 2);
                            basePolicyNumber = basePolicyNumber + "00";

                            finalPolicyName = Path.GetFileName(file);

                            PolicyUUID = Transporter.GetPolicyUUID(AppVars.pxCentralRootURL, basePolicyNumber);

                            if (PolicyUUID == "")
                            {
                                MessageBox.Show("The InsightPolicyID for the policy you are trying to upload does not exist in ixLibrary. Please ensure the policy number is correct. If you are sure it should be in ixLibray, please contact IT.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                            else
                            {
                                ixLibrarySourceFileURL = AppVars.ixLibraryPolicyAttachmentsURL + finalPolicyName;

                                UploadToixLibraryErrorCode = Transporter.UploadFileToixLibrary(AppVars.ixLibraryPolicyAttachmentsURL, file);

                                if (UploadToixLibraryErrorCode != 0)
                                {
                                    MessageBox.Show("There was an error uploading the file to ixLibrary. Please contact IT about this problem.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                }
                                else
                                {
                                    GeneratePayLoadErrorCode = Transformer.GeneratePayLoad(ixLibrarySourceFileURL, finalPolicyName);

                                    if (GeneratePayLoadErrorCode != 0)
                                    {
                                        MessageBox.Show("There was an error generating the XML for pxCentral. Please contact IT about this problem.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                    }
                                    else
                                    {
                                        pxCentralPOSTErrorCode = Transporter.pxCentralPOST(AppVars.pxCentralRootURL + PolicyUUID, AppVars.pxCentralXMLPayloadFilePath);

                                        pbValue = Convert.ToInt32(((current / count) * 30) + 70);

                                        uploadWorker.ReportProgress(pbValue);
                                    }
                                }
                            }
                        } 
                    }
                }
            }
        }

As soon as it hits the last }, I get the TargetInvocationException was unhandled error here (see comment in code):

static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            bool createdNew = false;

            Mutex mutex = new Mutex(true, "MyApplicationMutex", out createdNew);

            if (createdNew == true)
            {
                //error happens here
                Application.Run(new frmMain());
            }
            else
            {
                MessageBox.Show("The application is already running.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
    }

I'm not sure why this started happening all of the sudden. Does anyone know why?

Finally, here's RunWorkerCompleted:

private void uploadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                DeleteFinalFiles(finalFiles);
                MessageBox.Show("Upload process complete.", "Complete!", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            EnableAllButtons();
        }

Solution

  • You are calling EnableAllButtons in your DoWork handler. this, presumably, changes the Enabled state of buttons on the form. that is not legal from any other thread than the UI thread. You should make the call to EnableAllButtons in your ProgressChanged event handler or in your RunWorkerCompleted event handler. You're also calling ProgressBar.Value in the DoWork with the code pbUpload.Value = 0.

    Also, you should call MessageBox.Show from your UI thread (i.e. in ProgressChanged or RunworkerCompleted handler) so that the MessageBox can be associated with your forms message pump propertly. You should pass a form object to MessageBox.Show to associate the message box with the form so you can't bring the form to the foreground while the message box is shown. e.g.:

    MessageBox.Show(this, 
        "There are files in this folder that are not .tiff. Please ensure only .tiff files are in this folder.", 
        "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);