这是该函数最初的用法:
void fillLiguanea()
{
items = new List<string>();
this.liguanea_Lane2TableAdapter.Fill(this.pharmaciesDataSet3.Liguanea_Lane2);
try
{
string connectionString = "Data Source=LPMSW09000012JD\\SQLEXPRESS;Initial Catalog=Pharmacies;Integrated Security=True";
SqlConnection con = new SqlConnection(connectionString);
con.Open();
string query = "SELECT * FROM dbo.Liguanea_Lane2";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string scode = dr.GetString(dr.GetOrdinal("code"));
comboBox2.Items.Add(scode);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
现在考虑后台工作人员的方式如下:
private List <string> items;
void fillLiguanea()
{
items = new List<string>();
this.liguanea_Lane2TableAdapter.Fill(this.pharmaciesDataSet3.Liguanea_Lane2);
try
{
string connectionString = "Data Source=LPMSW09000012JD\\SQLEXPRESS;Initial Catalog=Pharmacies;Integrated Security=True";
SqlConnection con = new SqlConnection(connectionString);
con.Open();
string query = "SELECT * FROM dbo.Liguanea_Lane2";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string scode = dr.GetString(dr.GetOrdinal("code"));
// comboBox2.Items.Add(scode);
items.Add(scode);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
下面是我的后台工作程序函数,它们已被编辑以填充有问题的comboBox,即comboBox2。 这是我的背景工作者:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
fillLiguanea();
}
这是我的RunWorkerCompleted:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (comboBox4.SelectedIndex == 0)
{
foreach (var item in items)
{
comboBox2.Items.Add(item);
}
}
}
我的问题是我哪里出错了?代码应该做的是根据combox4索引的选择从我的数据库中填充comboBox2。目前没有任何反应我哪里错了?
答案 0 :(得分:1)
使用BackgroundWorker
时,您可以考虑这样的模式:
处理DoWork
事件并在那里调用耗时的任务
○请记住,事件是在与UI线程不同的另一个线程中引发的,因此如果出于任何原因想要在事件中执行一些UI代码,则应使用Invoke
创建一个线程安全调用UI元素
○在DoWork中投入耗时的UI任务是没用的。因为任务应该使用Invoke
在UI线程中运行,它将使UI线程再次忙碌。
您可以处理RunWorkerCompleted
事件,以便在DoWork
完成工作后执行某些任务。例如,在DoWork
中加载数据后,您可以使用RunWorkerCompleted
中加载的数据来填充ComboBox
。
您应该调用组件的RunWorkerAsync
方法来开始处理DoWork
事件
○当使用组件实例运行异步任务时,无法使用同一组件启动另一个任务,因此为防止异常,您应检查this.backgroundWorker1.IsBusy
,如果组件不忙,请调用该方法。
该组件对错误报告或更改或取消执行的进度有很好的支持。要了解有关这些功能的更多信息,请查看documentations。
对于.NET 4.5及更高版本,您可以使用async/await模式执行异步任务。
示例强>
我想你目前有一个LoadData
方法:
public void LoadData()
{
this.categoryTableAdapter.Fill(this.testDBDataSet.Category);
}
并且您希望使用LoadData
加载的数据填充控件。因此,您可以像这样处理DoWork
和RunWorkerCompleted
:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
LoadData();
}
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
this.comboBox1.DataSource = this.testDBDataSet.Category;
this.comboBox1.DisplayMember = "Name";
}
此外,您应该在任务开始时调用RunWorkerAsync
,例如:
private void button1_Click(object sender, EventArgs e)
{
if (!this.backgroundWorker1.IsBusy)
this.backgroundWorker1.RunWorkerAsync();
}