r_pat72
asked on
Implmenting Threading (in Winforms C#)- Getting Error - Cross-thread operation not valid
Hi,
I am trying to implement Threading in my application. One of my method ia taking 2 to 3 mins time for getting data from SQL Server. So I have Implemented Threading for this.
But I am getting error InvalidOperation Exception - Cross-thread operation not valid: Control 'dataGridView1' accessed from a thread other than the thread it was created on.
Here is my sample code.
public partial class frmEmployee : Form
{
public frmEmployee()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkIt em(new WaitCallback(GetEmployeeDa ta));
}
private void GetEmployeeData(Object stateInfo)
{
DataAccessLayer db = new DataAccessLayer();
System.Linq.IQueryable<Emp loyee> emp = db.GetEmployee();
dataGridView1.DataSource = emp;
}
private void EmployeeData()
{
DataAccessLayer db = new DataAccessLayer();
System.Linq.IQueryable<Emp loyee> emp = db.GetEmployee();
dataGridView1.DataSource = emp;
}
private void button2_Click(object sender, EventArgs e)
{
SecondMethod();
}
private static void SecondMethod()
{
MessageBox.Show("This is my second test message");
}
}
After clicking Button1, I clicked Button2 which display me the message "This is my second test message".
But after that I am getting, Cross-thread operation not valid.
Please help me with this.
Thanks!!!
I am trying to implement Threading in my application. One of my method ia taking 2 to 3 mins time for getting data from SQL Server. So I have Implemented Threading for this.
But I am getting error InvalidOperation Exception - Cross-thread operation not valid: Control 'dataGridView1' accessed from a thread other than the thread it was created on.
Here is my sample code.
public partial class frmEmployee : Form
{
public frmEmployee()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkIt
}
private void GetEmployeeData(Object stateInfo)
{
DataAccessLayer db = new DataAccessLayer();
System.Linq.IQueryable<Emp
dataGridView1.DataSource = emp;
}
private void EmployeeData()
{
DataAccessLayer db = new DataAccessLayer();
System.Linq.IQueryable<Emp
dataGridView1.DataSource = emp;
}
private void button2_Click(object sender, EventArgs e)
{
SecondMethod();
}
private static void SecondMethod()
{
MessageBox.Show("This is my second test message");
}
}
After clicking Button1, I clicked Button2 which display me the message "This is my second test message".
But after that I am getting, Cross-thread operation not valid.
Please help me with this.
Thanks!!!
public partial class frmEmployee : Form
{
public frmEmployee()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(GetEmployeeData));
}
private void GetEmployeeData(Object stateInfo)
{
DataAccessLayer db = new DataAccessLayer();
System.Linq.IQueryable<Employee> emp = db.GetEmployee();
dataGridView1.DataSource = emp;
}
private void EmployeeData()
{
DataAccessLayer db = new DataAccessLayer();
System.Linq.IQueryable<Employee> emp = db.GetEmployee();
dataGridView1.DataSource = emp;
}
private void button2_Click(object sender, EventArgs e)
{
SecondMethod();
}
private static void SecondMethod()
{
MessageBox.Show("This is my second test message");
}
}
It is illegal to make cross thread calls to the UI thread as far as I know, but You should be abe to override the default behaivor using:
private void GetEmployeeData(Object stateInfo)
{
// Disable the checking for illegal crossthread calls
Control.CheckForIllegalCro ssThreadCa lls = false;
// Rest of code...
DataAccessLayer db = new DataAccessLayer();
System.Linq.IQueryable<Emp loyee> emp = db.GetEmployee();
dataGridView1.DataSource = emp;
}
Just add the extra line to all method making cross thread calls. But notice that this is NOT the best solution, it's simply disabling the checking.
/Carl.
private void GetEmployeeData(Object stateInfo)
{
// Disable the checking for illegal crossthread calls
Control.CheckForIllegalCro
// Rest of code...
DataAccessLayer db = new DataAccessLayer();
System.Linq.IQueryable<Emp
dataGridView1.DataSource = emp;
}
Just add the extra line to all method making cross thread calls. But notice that this is NOT the best solution, it's simply disabling the checking.
/Carl.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
when updating controls on a separate thread, check first InvokeRequired because directly updating the properties of the control on another thread is not allowed.
margajet24 is absolutely correct, I'm a VB guy, don't know the actual implementation i C#...
dataGridView1.DataSource = emp;
I don't think you can data bind a datagrid on a thread other than the thread where the control was created. You might want to perform data binding inside the OnLoad override, and just refresh the data (query from data source) during GetEmployeeData().