Thread Pool: Invalid cross-thread operation.

I am brand new when it comes to streaming, but I get an InvalidOperationException when using the following code. I understand that he is trying to access importFileGridView , but this was created by the UI thread that importFileGridView an exception. My question is: how can I solve this? Is it possible for GetAllImports to have a return type? How do I access temp from my user interface thread?

 ThreadPool.QueueUserWorkItem(new WaitCallback(GetAllImports), null); private void GetAllImports(object x) { DataSet temp = EngineBllUtility.GetAllImportFiles(connectionString); if (temp != null) importFileGridView.DataSource = temp.Tables[0]; else MessageBox.Show("There were no results. Please try a different search", "Unsuccessful", MessageBoxButtons.OK, MessageBoxIcon.Information); } 
+4
source share
2 answers

You cannot change the user interface component in the background thread. In this case, the DataSource must be configured in the user interface thread.

You can handle this via Control.Invoke or Control.BeginInvoke , for example:

 private void GetAllImports(object x) { DataSet temp = EngineBllUtility.GetAllImportFiles(connectionString); if (temp != null) { // Use Control.Invoke to push this onto the UI thread importFileGridView.Invoke((Action) () => { importFileGridView.DataSource = temp.Tables[0]; }); } else MessageBox.Show("There were no results. Please try a different search", "Unsuccessful", MessageBoxButtons.OK, MessageBoxIcon.Information); } 
+2
source

Which reed said, but I like this syntax a little better:

What happens is that you create a delegate function that will be passed as a parameter to the user interface thread through Control.Invoke , which calls it, so the user interface thread makes changes to importFileGridView .

 importFileGridView.Invoke((MethodInvoker) delegate { importFileGridView.DataSource = temp.Tables[0]; }); 

You can also write this as follows:

 //create a delegate with the function signature public delegate void SetDateSourceForGridViewDelegate (GridView gridView, Object dataSource); //write a function that will change the ui public void SetDataSourceForGridView(GridView gridView, Object dataSource) { gridView.DataSource = dataSource; } //Create a variable that will hold the function SetDateSourceForGridViewDelegate delegateToInvoke = SetDataSourceForGridView; //tell the ui to invoke the method stored in the value with the given paramters. importFileGridView.Invoke(delegateToInvoke, importFileGridView, temp.Tables[0]); 

and I would suggest using MethodInvoker over Action here: here

0
source

Source: https://habr.com/ru/post/1388487/


All Articles