title: "BindingSource can't be its own DataSource"
body: <p>I'm working on a C# WinForms application which reads data into DataGridViews and exports those into an Excel worksheet with Excel Interop.</p>
  
  <p>Recently, there has sometimes been a strange error that hasn't (to my knowledge) happened before. During the Excel export that happens in a different thread, the error "BindingSource can't be its own DataSource" is thrown. Not everytime, only sometimes and seemingly random.</p>
  
  <p>I researched this error a bit and it seems the error occurs when you try to update a DataGridView from an external thread without Invokes. The Export function receives the DataGridView as an argument (wasn't done by me and would be too much work to change everywhere) and then loops the rows and columns to get the data into the Excel. I don't update anything in the DataGridView, but maybe there is something else that causes this error.</p>
  
  <p>My question is: Does someone know exactly which types of access require making an additional Invoker function to call the grid from UI instead of in the thread? For example, can I ask a <code>grid.Rows[i].Cells[j].Value</code> without Invoke (using the grid that is an argument). Can I loop through columns or ask a column name with <code>DataGridViewColumn.Name</code>? A Column Index? Ask if <code>grid.Columns.Contains("name")</code>?</p>
  
  <p>I need to know what I need to make thread safe in order to prevent this error from occuring. And if someone knows anything about this error that I haven't mentioned here, I would appreciate it if you could help me in this regard too. Thanks for you help.</p>
  
  <p>Edit:
  Code samples:</p>
  
  <pre><code>        //param is an object[] that contains all the parameters, 
          //including "grid", the DataGridView
          private void ExportToExcel(object param)
          {
          //declare variables, start excel, nothing relevant before this
          ...
              for (int k = 0; k &lt; grid.Rows.Count; k++) // Zeilen durchgehen
              {
                  DataGridViewRow row = grid.Rows[k];
                  if (!row.Visible)
                      continue;
  
                  for (int j = 0; j &lt; grid.Columns.Count; j++)
                  {
                     string colName = grid.Columns[i].Name;
                     if(colName == "FirstColumn")
                     {
                         //format excel cell for firstcolumn
                         ...
                         worksheet.Cells[i, j + 1] = row.Cells[j].Value.ToString();
                     }
                     ...
                  }
               ...
               }
            ...
        }
  
        //call of excel function
        object[] params = new object[]{this.dgvGrid, other, parameters}
        Thread excelThread = new Thread(new ParameterizedThreadStart(ExportToExcel));
        excelThread.Start(params);
  </code></pre>
  
  <p>Edit2: All the interactions I do with DataGridView in this function.</p>
  
  <pre><code>//Retrieve:
  grid.Rows[i]
  row.Visible
  row.Cells[column.Name].Value
  grid.Columns.Count
  grid.Columns.Contains(name)
  column.DataPropertyName
  cell.ValueType
  column.HeaderText
  </code></pre>
  
  <p>I thoroughly scanned the whole function. In no place is there an assignment to a DataGridView-related object. In only retrieve the above things. The cell values are stored in local variables and manipulated ( <code>object val = grid.Cells[j].Value; val = val.ToString() + "%";</code>)</p>