1
votes

I am unable to get the reason for this Exception:

private void bwWorker_DoWork(object sender, DoWorkEventArgs e)
{
   if (Main.bolDebugMode)
      MessageBox.Show("Function DoWork is called");
   if (Main.ftpsync(Main.strUsername407, Main.strPassword407, sender as BackgroundWorker) == 0)
      e.Result = e.Result + "No error in " + Main.strUsername407;
   else
   {
      if (Main.bolDebugMode)
         MessageBox.Show("Errors in " + Main.strUsername407);
      e.Cancel = true;
      e.Result = e.Result + "Errors in " + Main.strUsername407;
      if (Main.bolDebugMode)
         MessageBox.Show("Errors marked");
      try
      {
         MessageBox.Show("Next step throws exception");
         return;
      }
      catch (Exception error)
      {
          if (error.ToString() != null)
             MessageBox.Show(error.InnerException.Message);
      }
   }
}

It throws this exception:

An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll

Additional information: Exception has been thrown by the target of an invocation.

The target (to my limited understanding) is the backgroundworker's RunWorkerCompleted function:

 private void bwWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (Main.bolDebugMode)
                MessageBox.Show("DoWork Completed. Break: " + e.Cancelled + " Error: " + e.Error + " Result: " + e.Result);

            // First, handle the case where an exception was thrown.
            if (e.Error != null)
            {
                lStatus.Text = e.Error.Message;
            }
            else if (e.Cancelled)
                lStatus.Text = "Cancelled: " + e.Result.ToString();
            }
            else
            {
                lStatus.Text = "Done! " + e.Result;
                Thread.Sleep(Convert.ToInt16(Main.strGlobalWaitTime));
                pbProgress.Value = 0;
                lStatus.Text = "";
            }

            if (Main.bolDebugMode)
                MessageBox.Show("Analysis completed");

            // Enable the Start button.
            btnStart.Enabled = true;

            // Disable the Cancel button.
            btnCancel.Enabled = false;
        }
public class Main
{
    #region Variables
    // Variables - FTP Settings
    // Reading tons of variables from a appconfig file like so:
    private static string StrGlobalWaitTime = ConfigurationManager.AppSettings["program_globalWaitTime"]; 
    private static bool BolDeleteRemoteFiles = Convert.ToBoolean(ConfigurationManager.AppSettings["program_deleteremotefiles"]);

    // Configuring the variables to receive and write
    public static string strGlobalWaitTime
    {
        get { return StrGlobalWaitTime; }
        set { StrGlobalWaitTime = value; }
    }
    #endregion

    #region Main function
    public static int ftpsync(string strUsername, string strPassword, BackgroundWorker bwWorker)
    {
        if (Directory.EnumerateFiles(strWorkDirectory, "*.pdf").Any())
        {
            bwWorker.ReportProgress(0, "Files left! Upload not complete");
            Thread.Sleep(Convert.ToInt16(Main.strGlobalWaitTime));
            return 1;
        }

However, it doesn't even reach the first debugging message box. Thus it must be happening between the return and the beginning of the function. Is he background worker not handing over directly to the RunWorkerCompleted function? Can anyone tell me what I am missing or doing wrong?

This is my first question. I will try to provide as much information as possible. Google searches for the most obvious queries have been done.
1
You can't be accessing GUI controls in the DoWork method since that is on a different thread. Pass all of the information you need as a parameter when you call your RunWorkerAsync. - LarsTech
As far as I know I am not accessing any GUI controls in my DoWork. The "Main."xx are all parts of a separate class. - RobSteward
Calling MessageBox.Show is accessing GUI thread. - Crono
We don't know much about that Main class of yours. - LarsTech
You will want to learn how to use Enum types next. :) - Crono

1 Answers

3
votes

The thing to look for whenever you encounter a TargetInvocationException is the InnerException property, which will have the "real" exception.

From the look of it, it will most likely have something to do with trying to access the GUI from inside the worker's thread. Remember that when using the DoWork handler, the code executes in a different thread from the main UI's. Therefore, calls to GUI components must be either done via Invoke calls or avoided all together.