如何在单独的线程中启动长时间运行的进程 [英] How to start a long running process in a separate thread
问题描述
好的,我们到最后一步几乎完成了!一个错误. 这是在使用建议,并且在抱怨我认为的代表.
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?
推荐答案
修复了一些较小的拼写错误,当时还没有编译器. 对于最后一个错误:只需将accCollection.Text作为参数提供给您的方法.请参阅更新的button1_Click()和GetsalesFigures(String Acct). 这就是我的Partial Class:Form的样子
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);
}
}
和Program.cs
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.
您可能要检查多线程/任务的某些资源 http://msdn.microsoft.com/en-us /library/system.threading.tasks.task.aspx http://blogs.msdn.com/b/pfxteam/archive/2009/06/30/9809774.aspx
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
这篇关于如何在单独的线程中启动长时间运行的进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!