title: Error: Invoke or BeginInvoke cannot be called on a control until the window handle has been created
body: <p>Firstly, let me say that I've been on this issue for pretty much 2 days now: tried various alternatives and read tons of questions from your site with similar issues.</p>
  
  <p>First let me paste my code so you get the whole picture.</p>
  
  <p><strong>EDIT:</strong> Removed some code that might be unnecessary to the problem, based on request by forum member.</p>
  
  <p><strong>Form 1.cs</strong></p>
  
  <pre><code>namespace TestApp
  {
  
  public partial class Form1 : Form    
  {
      //global declarations
      private static Form1 myForm;
      public static Form1 MyForm
      {
          get
          {
              return myForm;
          }
      }       
      List&lt;DataSet&gt; DataSets = new List&lt;DataSet&gt;();
      int typeOfDataset = 0;
      //delegate for background thread to communicate with the UI thread _
      //and update the metadata autodetection progress bar
      public delegate void UpdateProgressBar(int updateProgress);
      public UpdateProgressBar myDelegate;
  
  
      //***************************
      //****  Form Events  ********
      //***************************
  
      public Form1()
      {
         InitializeComponent();
         if (myForm == null)
         {
             myForm = this;
         }
         DataSets.Add(new DSVDataSet());
         DataSets[typeOfDataset].BWorker = new BackgroundWorker();
         DataSets[typeOfDataset].BWorker.WorkerSupportsCancellation = true;
         myDelegate = new UpdateProgressBar(UpdateProgressBarMethod);
       }
  
      private void Form1_FormClosing(object sender, FormClosingEventArgs e)
      {
          //e.Cancel = true;
          if (DataSets[typeOfDataset].BWorker != null || DataSets[typeOfDataset].BWorker.IsBusy)
          {
              Thread.Sleep(1000);
              DataSets[typeOfDataset].BWorker.CancelAsync();
          }
          Application.Exit();
      }
  
      //***************************
      //***  Menu Items Events  ***
      //***************************
  
      private void cSVToolStripMenuItem_Click(object sender, EventArgs e)
      {
          LoadFillDSVData(',');
      }
  
      //***************************
      //*** DataGridViews Events **
      //***************************
  
      private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
      {
          using (SolidBrush b = new SolidBrush(this.dataGridView1.RowHeadersDefaultCellStyle.ForeColor))
          {
              e.Graphics.DrawString(e.RowIndex.ToString(System.Globalization.CultureInfo.CurrentUICulture), this.dataGridView1.DefaultCellStyle.Font, b, e.RowBounds.Location.X + 20, e.RowBounds.Location.Y + 4);
          }
          int rowHeaderWidth = TextRenderer.MeasureText(e.RowIndex.ToString(), dataGridView1.Font).Width;
          if (rowHeaderWidth + 22 &gt; dataGridView1.RowHeadersWidth)
          {
              dataGridView1.RowHeadersWidth = rowHeaderWidth + 22;
          }
      }
  
      private void dataGridView2_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
      {
          using (SolidBrush b = new SolidBrush(this.dataGridView2.RowHeadersDefaultCellStyle.ForeColor))
          {
              e.Graphics.DrawString(e.RowIndex.ToString(System.Globalization.CultureInfo.CurrentUICulture), this.dataGridView2.DefaultCellStyle.Font, b, e.RowBounds.Location.X + 20, e.RowBounds.Location.Y + 4);
          }
          int rowHeaderWidth = TextRenderer.MeasureText(e.RowIndex.ToString(), dataGridView2.Font).Width;
          if (rowHeaderWidth + 22 &gt; dataGridView2.RowHeadersWidth)
          {
              dataGridView2.RowHeadersWidth = rowHeaderWidth + 22;
          }
      }
  
      //***************************
      //****** Other Methods ******
      //***************************
  
      private void LoadFillDSVData(char delimiter)
      {
          //load file through openFileDialog
          //some more openFileDialog code removed for simplicity
          if (DataSets[typeOfDataset].BWorker != null || DataSets[typeOfDataset].BWorker.IsBusy)
          {
              Thread.Sleep(1000);
              DataSets[typeOfDataset].BWorker.CancelAsync();
              DataSets[typeOfDataset].BWorker.Dispose();
          }
          //if file was loaded, instantiate the class
          //and populate it 
          dataGridView1.Rows.Clear();
          dataGridView2.Rows.Clear();
          typeOfDataset = 0;
          DataSets[typeOfDataset] = new DSVDataSet();
          DataSets[typeOfDataset].DataGrid = this.dataGridView1;
          DataSets[typeOfDataset].BWorker = new BackgroundWorker();
          DataSets[typeOfDataset].InputFile = openFileDialog1.FileName;
          DataSets[typeOfDataset].FileName = Path.GetFileName(DataSets[typeOfDataset].InputFile);
          DataSets[typeOfDataset].InputPath = Path.GetDirectoryName(DataSets[typeOfDataset].InputFile);
          DataSets[typeOfDataset].Delimiter = delimiter;
          //read file to get number of objects and attributes
          DataSets[typeOfDataset].LoadFile(DataSets[typeOfDataset].InputFile, DataSets[typeOfDataset].Delimiter);
          //ask to autodetect metadata
          DialogResult dr = MessageBox.Show("Auto detect attributes?", "TestApp", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
          switch (dr)
          {
              case DialogResult.Yes:
                  toolStripStatusLabel1.Text = "Autodetecting attributes...";
                  toolStripProgressBar1.Value = 0;
                  toolStripProgressBar1.Maximum = 100;
                  toolStripProgressBar1.Style = ProgressBarStyle.Continuous;
                  DataSets[typeOfDataset].AutoDetectMetadata(DataSets[typeOfDataset].Attributes);
                  break;
              case DialogResult.No: 
                  break;
              default: 
                  break;
          }
      }
  
      public void UpdateProgressBarMethod(int progress)
      {
          if (progress &gt; 99)
          {
              toolStripProgressBar1.Value = progress;
              toolStripStatusLabel1.Text = "Done.";
          }
          else
          {
              toolStripProgressBar1.Value = progress;
          }
      } 
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>And one more class:</p>
  
  <p><strong>DSVDataSet.cs</strong></p>
  
  <pre><code>namespace TestApp
  {
  
  public class DSVDataSet : DataSet
  {
      static Form1 myForm = Form1.MyForm;
      //constructor(s)
      public DSVDataSet()
      {           
          InputType = DataSetType.DSV;
      }
  
  
      //autodetects metadata from the file if
      //the user wishes to do so
      public override void AutoDetectMetadata(List&lt;Attribute&gt; attributeList)
      {
          BWorker.WorkerReportsProgress = true;
          BWorker.WorkerSupportsCancellation = true;
          BWorker.DoWork += worker_DoWork;
          BWorker.ProgressChanged += worker_ProgressChanged;
          BWorker.RunWorkerCompleted += worker_RunWorkerCompleted;
  
          //send this to another thread as it is computationally intensive
          BWorker.RunWorkerAsync(attributeList);
      }
  
      private void worker_DoWork(object sender, DoWorkEventArgs e)
      {
          List&lt;Attribute&gt; attributeList = (List&lt;Attribute&gt;)e.Argument;
          using (StreamReader sr = new StreamReader(InputFile))
          {
              for (int i = 0; i &lt; NumberOfAttributes; i++)
              {
                  Attribute a = new Attribute();
                  attributeList.Add(a);
              }
              for (int i = 0; i &lt; NumberOfObjects; i++)
              {
                  string[] DSVLine = sr.ReadLine().Split(Delimiter);
                  int hoistedCount = DSVLine.Count();
                  string str = string.Empty;
                  for (int j = 0; j &lt; hoistedCount; j++)
                  {
                      bool newValue = true;
                      str = DSVLine[j];
                      for (int k = 0; k &lt; attributeList[j].Categories.Count; k++)
                      {
                          if (str == attributeList[j].Categories[k])
                          {
                              newValue = false;
                          }
                      }
                      if (newValue == true)
                      {
                          attributeList[j].Categories.Add(str);
                          //removed some code for simplicity
                      }
                  }
                  int currentProgress = (int)((i * 100) / NumberOfObjects);
                  if (BWorker.CancellationPending)
                  {
                      Thread.Sleep(1000);
                      e.Cancel = true;
                      return;
                  }
                  BWorker.ReportProgress(currentProgress); //report progress
              }
          }          
          e.Result = 100; //final result (100%)     
      }
  
      private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
      {
          int update = e.ProgressPercentage;
          myForm.BeginInvoke(myForm.myDelegate, update);
      }
  
      private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {               
  
          if (e.Error != null)
          {
              return;
          }
          if (e.Cancelled)
          {
              return;
          }
          else
          {
              int update = (int)e.Result;
              myForm.Invoke(myForm.myDelegate, update);
              for (int i = 0; i &lt; Attributes.Count; i++)
              {
                  DataGridViewRow item = new DataGridViewRow();
                  item.CreateCells(DataGrid);
                  item.Cells[0].Value = Attributes[i].Name;
                  switch (Attributes[i].Type)
                  {
                      case AttributeType.Categorical:
                          item.Cells[1].Value = "Categorical";
                          break;
                      //removed some cases for simplicity
                      default:
                          item.Cells[1].Value = "Categorical";
                          break;
                  }
                  item.Cells[2].Value = Attributes[i].Convert;
                  DataGrid.Rows.Add(item);
              }
              BWorker.Dispose();
          }
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Long story short, I have a backGroundWorker in DSVDataset.cs that does some 'heavy computation' so the UI doesn't freeze (new to this), and I use a delegate to have the background thread to communicate with the UI thread to update some progress bar values. If the user decides to make a new DSVDataSet (through cSVToolStripMenuItem_Click or tSVToolStripMenuItem_Click) then I've added some ifs wherever I've found appropriate that check if there's already a backGroundWorker running: if there is, call CancelAsync so it stops whatever it's doing and then .Dispose it.
  Now, sometimes when I try to exit the Form1 while a backGroundWorker might be running (check for example Form1_FormClosing) I get the error that is in the title of this post. The error takes me to this chunk of code in DSVDataSet.cs:</p>
  
  <pre><code>    private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
      {
          int update = e.ProgressPercentage;
          myForm.BeginInvoke(myForm.myDelegate, update);
      }
  </code></pre>
  
  <p>Pressing F10 takes me to Program1.cs:</p>
  
  <pre><code>   Application.Run(new Form1());
  </code></pre>
  
  <p>Based on another stackoverflow post I read (http://stackoverflow.com/questions/513131/c-sharp-compile-error-invoke-or-begininvoke-cannot-be-called-on-a-control-unti , look at the answer), I implemented that logic by exposing the instance of the Main class itself so it always points to this instance of main.
  So in Form1.cs:</p>
  
  <pre><code>private static Form1 myForm;
      public static Form1 MyForm
      {
          get
          {
              return myForm;
          }
      }       
   public Form1()
      {
         InitializeComponent();
         if (myForm == null)
         {
             myForm = this;
         }
       }
  </code></pre>
  
  <p>And in DSVDataset.cs:</p>
  
  <pre><code>  static Form1 myForm = Form1.MyForm;
  </code></pre>
  
  <p>and I use myForm wherever needed.</p>
  
  <p>Still, I'm not able to get past that error, so I can only assume I haven't implemented that solution correctly, or I'm doing something wrong with handling the backGroundWorkers.
  Any help would be greatly appreciated and I did my best to be as detailed as a could (hope this wasn't an overkill :)</p>
  
  <p>Regards</p>