Possible Duplicate:
How to update GUI from another thread in C#?
I've currently got a C# program to run a query and display the results in a datagridview.
The query due to size of records takes a while (20-30 seconds) to run.
I thought I would add an animation so the user at least knows the software is running and has not stopped working.
Of course I can't run anything when the call is being made to the procedure so I looked into threading.
Here is my code (forgive me, I haven't really put in comments yet):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Threading;
namespace RepSalesNetAnalysis
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            pictureBox2.Visible = false;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            GetsalesFigures();   
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            AutofillAccounts();
        }
        private void GetsalesFigures()
        {
            try
            {
                string myConn = "Server=herp;" +
                            "Database=shaftdata;" +
                            "uid=fake;" +
                            "pwd=faker;" +
                            "Connect Timeout=120;";
                string acct;// test using 1560
                SqlConnection conn = new SqlConnection(myConn);
                SqlCommand Pareto = new SqlCommand();
                BindingSource bindme = new BindingSource();
                SqlDataAdapter adapt1 = new SqlDataAdapter(Pareto);
                DataSet dataSet1 = new DataSet();
                DataTable table1 = new DataTable();
                Thread aniSql = new Thread(new ThreadStart(animateIcon));//CREATE THE THREAD
                acct = accCollection.Text;
                string fromDate = this.dateTimePicker1.Value.ToString("MM/dd/yyyy");
                string tooDate = this.dateTimePicker2.Value.ToString("MM/dd/yyyy");
                Pareto.Connection = conn;
                Pareto.CommandType = CommandType.StoredProcedure;
                Pareto.CommandText = "dbo.GetSalesParetotemp";
                Pareto.CommandTimeout = 120;
                Pareto.Parameters.AddWithValue("@acct", acct);
                Pareto.Parameters.AddWithValue("@from", fromDate);
                Pareto.Parameters.AddWithValue("@too", tooDate);
                aniSql.Start();                //START THE THREAD!
                adapt1.Fill(dataSet1, "Pareto");
                aniSql.Abort();                //KILL THE THREAD!
                //pictureBox2.Visible = false;
                this.dataGridView1.AutoGenerateColumns = true;
                this.dataGridView1.DataSource = dataSet1;
                this.dataGridView1.DataMember = "Pareto";
                dataGridView1.AutoResizeColumns(
                    DataGridViewAutoSizeColumnsMode.AllCells);
            }
            catch (Exception execc)
            {
                MessageBox.Show("Whoops! Seems we couldnt connect to the server!"
                            + " information:\n\n" + execc.Message + execc.StackTrace,
                            "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                }
        }
        private void AutofillAccounts()
        {
            //get customers list and fill combo box on form load.
            try
            {
                string myConn1 = "Server=derp;" +
                                "Database=AutoPart;" +
                                "uid=fake;" +
                                "pwd=faker;" +
                                "Connect Timeout=6000;";
                SqlConnection conn1 = new SqlConnection(myConn1);
                conn1.Open();
                SqlCommand accountFill = new SqlCommand("SELECT keycode FROM dbo.Customer", conn1);
                SqlDataReader readacc = accountFill.ExecuteReader();
                while (readacc.Read())
                {
                    this.accCollection.Items.Add(readacc.GetString(0).ToString());
                }
                conn1.Close();
            }
            catch(Exception exc1)
            {
                MessageBox.Show("Whoops! Seems we couldnt connect to the server!"
                            + " information:\n\n" + exc1.Message + exc1.StackTrace,
                            "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }
        public void animateIcon()
        {
            // animate
            pictureBox2.Visible = true;  
        }
    }
}
As you can see I want to run the animation just before the procedure call and then end it just after.
My knowledge on threads is brand new. I've looked around but i'm getting a little confused at the moment.
Here's my error:
Thrown: "Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on." (System.InvalidOperationException) Exception Message = "Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.", Exception Type = "System.InvalidOperationException"
I need a very simple way of performing an animation while my sql proc is reading.
Something like picture.visible = true when its started and false when it ends.
 
     
     
     
     
     
    