我理解线程的概念,但我一般都是新手,所以请耐心等待。如果这是一个无趣的问题,请道歉。
我需要在Windows窗体程序中对Oracle数据库运行一些密集查询。虽然此代码可以正常工作,但程序会冻结,因为查询可能需要一分钟才能运行,而且我按顺序运行了几个。我认为创建一个单独的线程,如下所示,可以防止这种情况发生。我是否需要在创建线程时指定一些内容,表明只有一定数量的资源应该专用于它?我在Google上找到了一些答案,但并没有真正了解它们。
提前感谢您的帮助!
private void loginButton_Click(object sender, EventArgs e)
{
loginStatus.Text = "STATUS: Running...";
Thread thread1 = new Thread(new ThreadStart(GetLoginData));
thread1.Start();
loginStatus.Text = "STATUS: Ready";
}
private void GetLoginData()
{
try
{
Invoke(new Action(() => loginButton.Enabled = false));
string LDS01_start = "select count(*) from BBLEARN.AUTH_PROVIDER_LOG where AUTH_PROVIDER_PK1 = 103 ";
string LDAPS_start = "select count(*) from BBLEARN.AUTH_PROVIDER_LOG where AUTH_PROVIDER_PK1 = 106 ";
string middle = "and log_date >= '" + GetDate(loginStartDate) + @"'
and log_date < '" + GetDate(loginEndDate) + @"' ";
string LDS01_0 = LDS01_start + middle + "and event_type = 0";
string LDS01_1 = LDS01_start + middle + "and event_type = 1";
string LDS01_2 = LDS01_start + middle + "and event_type = 2";
string LDS01_5 = LDS01_start + middle + "and event_type = 5";
string LDS01_6 = LDS01_start + middle + "and event_type = 6";
string LDAPS_0 = LDAPS_start + middle + "and event_type = 0";
string LDAPS_1 = LDAPS_start + middle + "and event_type = 1";
string LDAPS_2 = LDAPS_start + middle + "and event_type = 2";
string LDAPS_5 = LDAPS_start + middle + "and event_type = 5";
string LDAPS_6 = LDAPS_start + middle + "and event_type = 6";
Invoke(new Action(() => GetData(LDS01_0, LDS01_LB0)));
Invoke(new Action(() => GetData(LDS01_1, LDS01_LB1)));
Invoke(new Action(() => GetData(LDS01_2, LDS01_LB2)));
Invoke(new Action(() => GetData(LDS01_5, LDS01_LB5)));
Invoke(new Action(() => GetData(LDS01_6, LDS01_LB6)));
Invoke(new Action(() => GetData(LDAPS_0, LDAPS_LB0)));
Invoke(new Action(() => GetData(LDAPS_1, LDAPS_LB1)));
Invoke(new Action(() => GetData(LDAPS_2, LDAPS_LB2)));
Invoke(new Action(() => GetData(LDAPS_5, LDAPS_LB5)));
Invoke(new Action(() => GetData(LDAPS_6, LDAPS_LB6)));
Invoke(new Action(() => loginButton.Enabled = true));
loginStatus.Text = "STATUS: Ready";
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
private void GetData(string selectCommand, Label label)
{
//open the connection
OracleConnection conn = new OracleConnection(connectString);
conn.Open();
//define the command
selectCommand = selectCommand.Replace(Environment.NewLine, " ");
OracleDataAdapter dataAdapter = new OracleDataAdapter(selectCommand, conn);
OracleCommandBuilder commandBuilder = new OracleCommandBuilder(dataAdapter);
//run the command
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
dataAdapter.Fill(table);
//pull the result
label.Text = table.Rows[0][0].ToString();
//close the connection
conn.Close();
}
答案 0 :(得分:2)
你是invoking
GetData()
方法,调用使用UI线程,GetData()方法是针对数据库的,并且花费时间让你的屏幕锁定。你需要简单地调用UI更改然后线程关闭数据库调用,完成后调用UI线程启用按钮等...
从GetLoginData()
更改您的来电:
Invoke(new Action(() => GetData(LDS01_0, LDS01_LB0)));
对此:
GetData(LDS01_0, LDS01_LB0);
将GetData()更改为:
private void GetData(string selectCommand, Label label)
{
//open the connection
OracleConnection conn = new OracleConnection(connectString);
conn.Open();
//define the command
selectCommand = selectCommand.Replace(Environment.NewLine, " ");
OracleDataAdapter dataAdapter = new OracleDataAdapter(selectCommand, conn);
OracleCommandBuilder commandBuilder = new OracleCommandBuilder(dataAdapter);
//run the command
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
dataAdapter.Fill(table);
//close the connection
conn.Close();
Invoke(new Action(() => RenderData(label, table.Rows[0][0].ToString())));
}
创建这个新的RenderData()方法:
private void RenderData(Label label, string text)
{
label.Text = text;
}