Link to home
Start Free TrialLog in
Avatar of inimicaljords
inimicaljordsFlag for United States of America

asked on

c# cross-thread operation not valid

This is my first attempt of using a different thread so I am new to this.  I am getting the cross-thread operation not valid error on a trackbar event because it is on the main UI thread.  I have read about having to use the invoke process, but I am not real sure how it works.

My program basically loops through a SQL CE database and pulls out all of the ip addresses and then calls an isalive function to test if the ip address is pingable or not.  I have added an additional feature of a trackbar to determine the timeout of the ping request.

All of these features work fine on the main UI thread.  Now, I want to use the backgroundworker so the UI doesn't have a freezing like effect to it while the scan is in progress.  I also would like to add a stop button that stops the background thread.

Here is the IsAlive Function with tbSpeed being the trackbar:
        public bool IsAlive(string aIP)
        {
            bool result = false;
            Ping pingSender = new Ping();
            PingOptions options = new PingOptions();
            options.DontFragment = true;
            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            int timeout = 0;
            if (tbSpeed.Value == 0)
                timeout = 6000;
            else if (tbSpeed.Value == 1)
                timeout = 4500;
            else if (tbSpeed.Value == 2)
                timeout = 3000;
            else if (tbSpeed.Value == 3)
                timeout = 1500;
            else if (tbSpeed.Value == 4)
                timeout = 100;
            PingReply reply = pingSender.Send(aIP, timeout, buffer, options);
            if (reply.Status == IPStatus.Success)
                result = true;
            return result;
        }

Open in new window


My scan button:
        public void btnScan_Click(object sender, EventArgs e)
        {
            //Clears labels, grid, and progress bar
            dg1.Rows.Clear();
            pbScan.Value = 0;
            pbScan.Visible = true;
            lbTotal.Text = "";
            lbAlive.Text = "";
            lbDead.Text = "";

            backgroundWorker1.RunWorkerAsync();

        }

Open in new window


My backgroundworker code:
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            cn.Open();

            string aTable = "0";
            if (rbKiosk.Checked)
                aTable = "kiosk";
            else if (rbShower.Checked)
                aTable = "shower";
            else if (rbJPROap.Checked)
                aTable = "jproAP";

            string SQL = ("Select * from " + aTable + " ORDER BY site");
            SqlCeCommand cmd = new SqlCeCommand(SQL, cn);
            cmd.CommandType = CommandType.Text;

            int x = 0;
            int a = 0;
            int d = 0;
            int t = 0;
            try
            {
                SqlCeDataReader dtr = cmd.ExecuteReader(CommandBehavior.Default);
                while (dtr.Read())
                {
                    t = t + 1;
                    if (IsAlive((dtr.GetString(2))) == true)
                    {
                        sqlupdate((dtr.GetString(2)), aTable, "Alive", (dtr.GetString(3)), (dtr.GetString(4)), (dtr.GetString(5)), (dtr.GetString(6)), (dtr.GetString(7)), (dtr.GetString(8)), (dtr.GetString(9)), (dtr.GetString(10)), (dtr.GetString(11)), (dtr.GetString(13)), (dtr.GetString(14)), (dtr.GetString(15)), (dtr.GetString(16)), (dtr.GetString(17)), (dtr.GetString(18)), (dtr.GetString(19)), (dtr.GetString(20)), (dtr.GetString(21)));
                        string[] row = new string[] { (Convert.ToString(dtr.GetInt32(1))), (dtr.GetString(2)), "Alive", DateTime.Now.ToString() };
                        dg1.Rows.Add(row);
                        dg1.Rows[x].Cells[0].Style.BackColor = Color.Green;
                        dg1.Rows[x].Cells[1].Style.BackColor = Color.Green;
                        dg1.Rows[x].Cells[2].Style.BackColor = Color.Green;
                        dg1.Rows[x].Cells[3].Style.BackColor = Color.Green;
                        a = a + 1;
                    }
                    else
                    {
                        sqlupdate((dtr.GetString(2)), aTable, "Dead", (dtr.GetString(3)), (dtr.GetString(4)), (dtr.GetString(5)), (dtr.GetString(6)), (dtr.GetString(7)), (dtr.GetString(8)), (dtr.GetString(9)), (dtr.GetString(10)), (dtr.GetString(11)), (dtr.GetString(13)), (dtr.GetString(14)), (dtr.GetString(15)), (dtr.GetString(16)), (dtr.GetString(17)), (dtr.GetString(18)), (dtr.GetString(19)), (dtr.GetString(20)), (dtr.GetString(21)));
                        string[] row = new string[] { (Convert.ToString(dtr.GetInt32(1))), (dtr.GetString(2)), "Dead", DateTime.Now.ToString() };
                        dg1.Rows.Add(row);
                        dg1.Rows[x].Cells[0].Style.BackColor = Color.Red;
                        dg1.Rows[x].Cells[1].Style.BackColor = Color.Red;
                        dg1.Rows[x].Cells[2].Style.BackColor = Color.Red;
                        dg1.Rows[x].Cells[3].Style.BackColor = Color.Red;
                        d = d + 1;

                    }
                    Application.DoEvents();
                    pbScan.Value = x;
                    lbTotal.Text = "Total:  " + t;
                    lbAlive.Text = "Alive:  " + a;
                    lbDead.Text = "Dead:  " + d;
                    x = x + 1;
                }

            }
            catch (SqlCeException ex)
            {
                MessageBox.Show(ex.ToString());
            }

            finally
            {
                pbScan.Value = 215;
                cn.Close();
            }

Open in new window


I would assume that I am going to have the same error with the progress bar (pbScan) because it is on the main UI as well.  

What do I need to do to fix this?
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of inimicaljords

ASKER

Excellent information.  Your advice was very easy to understand.  I was able to get the progress bar and stop command to work perfectly.  I just had to comment out the track bar and datagrid items for testing.  

I am still confused on how to do the trackbar (tbSpeed) and datagridview (dg1) get called from the backgroundworker.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank so much for the help! Sorry for the delay in accepting the answers.  Had several things come up.  Your advice was greatly appreciated!!