This is the exception I'm getting:
"Cross-thread operation not valid: Control 'dgvLogResults' accessed from a thread other than the thread it was created on."
I'm trying to update a datagridview with new data that has been detected in a thread that is running and polling. But I can't seem to get this to work do I have to reference the original thread somehow then access the control

Accessing a DataGridView control from a thread that it wasn't created in???
ylmz
I'm really horrible with delegates still getting my head around them. So if I want access the DataGridView I write
public void myDelegate();
// Do I need to invoke to use this control
If( myDataGridView.InvokeRequired )
{
// Yes so call a delegate which points to a method in my class
myDataGridView.BeginInvoke( new myDelegate( AutoUpdateDGV ) );
}
public void AutoUpdateDGV()
{
// Update this control
}
I can see how this works... and this can all happen within my one class... ya I think I have it... Does this look okay Do I need to make a delegate like I did above You seem to be call a straight method or recursively calling if that second call to searchComplete isn't supposed to a lower case.
Zacharia
Use BeginInvoke on the form that contains the object. Depending on how you have it set up you might also want to use InvokeRequired.
I tend to use things like the following:
private void SearchComplete() { if (this.InvokeRequired) {BeginInvoke(searchComplete);
}
else { this.Cursor = Cursors.Default;}
}
Ceyhun PAK
Sorry, "searchComplete" is an instance of a delegate that referrs to "SearchComplete". The only change I would make would be to use a single method (with a sorta-recursive call using BeginInvoke).
So yours would be:
public void myDelegate();
public void AutoUpdateDGV(){
if (myDataGridView.InvokeRequired()){
myDataGridView.BeginInvoke(new myDelegate(AutoUpdateDGV));
}
else{
// update the data grid here
}
}
This allows all the code that is doing the update to be done in the same method.
I don't know if the above is really good practive, but it does work. I think the better practice is to call BeginInvoke from the method in the seperate thread. This requires that you design threads to know if they are updating the GUI and use the appropriate method to do so. One problem with the above method is that it does not allow the calling thread to distinguish between BeginInvoke and Invoke.
Coach David
hmmm I'm sorry I don't think I understand I put some of my code below the comments make it a quick read Only three methods...
// START THREAD
private void RunAutoUpdateDataLogViewerThread()
{
// Instantiate data log viewer auto update thread
tcpViewer =
new Thread(new ThreadStart(AutoUpdateDataLogViewer));
// Call thread start method to place thread in the running statetcpViewer.Start();
}
// RUNNING THREAD
private void AutoUpdateDataLogViewer(){
while (datalogScreen.Visible){
// Check IsDone reading transmitted data flag if (tcpManager.CheckTCPIsDoneReading()){
// Clear IsDone reading transmitted data flagtcpManager.ClearTCPIsDoneReading();
// Update DataGridView logged resultsUpdateDataGridView();
}
else{
// Put thread to sleep for five seconds Thread.Sleep(5000);}
}
}
// UPDATE DATAGRIDVIEW so this is the function I should use BeginInvoke() by putting it above by 7 or 8 lines like
BeginInvoke(UpdateDataGridView()); where I should make up a delegate for UpdateDataGridView()
// Update DataGridView logged results
public void UpdateDataGridView(){
// Build DataSet DataSet dbset = dbutes.BuildDataSet(BuildViewLoggingSQL(), "tblRdrLog"); // Fill DataGridView with logged dataFillDataGridView(dbset,
this.dgvLogResults);}
MrBobo
// UPDATE DATAGRIDVIEW so this is the function I should use BeginInvoke() by putting it above by 7 or 8 lines like
BeginInvoke(UpdateDataGridView()); where I should make up a delegate for UpdateDataGridView()
Correct, if you replace the direct call with a BeginInvoke you should be good.