Reputation: 2636
ok here we go last part almost done! one error to go hmmmmm. This is using the suggestion and is complaining about delegates i think.
using System;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pictureBox2.Visible = false;
}
private void button1_Click(object sender, EventArgs e)
{
Task t = new Task(() => GetsalesFigures(accCollection.Text));
t.Start();
}
private void SetPictureBoxVisibility(bool IsVisible)
{
if (pictureBox2.InvokeRequired)
{
pictureBox2.Invoke(new Action<bool>(SetPictureBoxVisibility), new Object[] { IsVisible });
}
else
{
pictureBox2.Visible = IsVisible;
}
}
private void SetCheckBoxValue(bool IsChecked)
{
if (checkBox1.InvokeRequired)
{
pictureBox2.Invoke(new Action<bool>(SetCheckBoxValue), new Object[] { IsChecked });
}
else
{
checkBox1.Checked = IsChecked;
}
}
private void AddItem(string value)
{
if (accCollection.InvokeRequired)
{
accCollection.Invoke(new Action<string>(AddItem), new Object[] { value });
}
else
{
accCollection.Items.Add(value);
}
}
private void Form1_Load(object sender, EventArgs e)
{
AutofillAccounts();
}
private void GetsalesFigures(string Acct)
{
try
{
string myConn = "Server=af" +
"Database=sdfta;" +
"uid=busdf4;" +
"pwd=drsdft;" +
"Connect Tisdf=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();
//CREATE THE THREAD
//acct = accCollection.Text;
acct = Acct;
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);
//pictureBox2.Visible = true;
//checkBox1.Checked = true;
SetCheckBoxValue(true);
SetPictureBoxVisibility(true);
adapt1.Fill(dataSet1, "Pareto");
//checkBox1.Checked = false;
//pictureBox2.Visible = false;
SetCheckBoxValue(false);
SetPictureBoxVisibility(true);
this.dataGridView1.AutoGenerateColumns = true;
this.dataGridView1.DataSource = dataSet1;
this.dataGridView1.DataMember = "Pareto";
dataGridView1.AutoResizeColumns(
DataGridViewAutoSizeColumnsMode.AllCells);
SetPictureBoxVisibility(true);
acct = Acct;
}
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=sdf33;" +
"Database=sdft;" +
"uid=bdf4;" +
"pwd=ddft;" +
"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())
{
AddItem(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);
}
}
}
}
not sure where the changes should be made, shouldnt it be in the account method now?
Upvotes: 0
Views: 3954
Reputation: 8116
Fixed some minor spelling errors, didn't have a compiler at hand back then. To your last error: Just provide the accCollection.Text as parameter to your method. See the updated button1_Click() and GetsalesFigures(String Acct). This is how my Partial Class : Form looks like
public Form1()
{
InitializeComponent();
pictureBox2.Visible = false;
}
private void Form1_Load(object sender, EventArgs e)
{
AutofillAccounts();
}
private void button1_Click(object sender, EventArgs e)
{
checkBox1.Checked = true;
string acct = accCollection.Text;
Task t = new Task(() => GetsalesFigures(acct));
t.Start();
}
private void GetsalesFigures(String Acct)
{
// (...)
//pictureBox2.Visible = true; use SetPictureBoxVisibility
SetPictureBoxVisibility(true);
//checkBox1.Checked = true; use SetCheckBoxValue
SetCheckBoxValue(true);
// (...)
SetCheckBoxValue(false);
SetPictureBoxVisibility(false);
// (...)
acct = Acct;
// (...)
SetDataGrid(true, dataSet1, "Pareto", DataGridViewAutoSizeColumnsMode.AllCells);
}
private void AutofillAccounts()
{
// (...)
while (readacc.Read())
{
AddItem(readacc.GetString(0).ToString());
}
}
private void SetCheckBoxValue(bool IsChecked)
{
if (checkBox1.InvokeRequired)
{
pictureBox2.Invoke(new Action<bool>(SetCheckBoxValue), new Object[] { IsChecked });
}
else
{
checkBox1.Checked = IsChecked;
}
}
private void SetPictureBoxVisibility(bool IsVisible)
{
if (pictureBox2.InvokeRequired)
{
pictureBox2.Invoke(new Action<bool>(SetPictureBoxVisibility), new Object[] { IsVisible });
}
else
{
pictureBox2.Visible = IsVisible;
}
}
// Your latest comment
private void AddItem(string value)
{
if (accCollection.InvokeRequired)
{
accCollection.Invoke(new Action<string>(AddItem), new Object[] { value });
}
else
{
accCollection.Items.Add(value);
}
}
private void SetDataGrid(bool AutoGenerateColumns, Object DataSource, String DataMember, DataGridViewAutoSizeColumnsMode Mode)
{
if (this.dataGridView1.InvokeRequired)
{
this.dataGridView1.Invoke(new Action<bool, Object, String, DataGridViewAutoSizeColumnsMode>(SetDataGrid),
AutoGenerateColumns, DataSource, DataMember, Mode);
}
else
{
this.dataGridView1.AutoGenerateColumns = AutoGenerateColumns;
this.dataGridView1.DataSource = DataSource;
this.dataGridView1.DataMember = DataMember;
dataGridView1.AutoResizeColumns(Mode);
}
}
And Program.cs
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
To summary your problem: You have to encapsulate all control-related updates you want to call from another thread than the main thread just like I did it with the two controls.
Some ressources you might want to check for multithreading / tasks http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx http://blogs.msdn.com/b/pfxteam/archive/2009/06/30/9809774.aspx
Upvotes: 1
Reputation: 16038
You have many problems in your code:
The call to Application.Run()
is a blocking call. It won't return until you close your form.
So your thread starts when your application is about to exit.
Just start your thread before calling Run():
Thread aniSql = new Thread(new ThreadStart(getSalesFigures));
aniSql.Start();
Application.Run(new Form1());
A Tip: Start using the debugger and step through your code. You would have noticed that your thread function is never reached.
You create a second instance of Form1 in the function GetSalesFigures
. You have to use the existing instance when polling the state of the checkbox.
Your thread will perform only a single check and then it returns. You have to write some code in GetSalesFigures
to wait for the user to check the checkbox. Otherwise nothing will happen.
You can use a ManualResetEvent
for waiting on an event:
ManualResetEvent mre = new ManualResetEvent(false);
void YourThreadFunc() {
// Wait until someone signals mre
mre.WaiteOne();
// start sql
...
}
In your form:
private void button1_Click(object sender, EventArgs e)
{
// trigger the WaitHandle to signal the waiting thread
mre.Set();
}
Upvotes: 2