问题
This is how the function was originally:
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());
}
}
This is how it looks now taking into consideration background worker:
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());
}
}
Below are my background worker functions which have been edited to populate the comboBox in question, which is comboBox2. This is my back ground worker:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
fillLiguanea();
}
This is my RunWorkerCOmpleted:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (comboBox4.SelectedIndex == 0)
{
foreach (var item in items)
{
comboBox2.Items.Add(item);
}
}
}
My question is where am I going wrong? what the code should do is populate comboBox2 from my database based on the selection of combox4's index. Currently nothing happens. Where am I going wrong?
回答1:
When using BackgroundWorker you can consider such pattern:
Handle
DoWorkevent and call the time-consuming task there.
○ Keep in mind the event is raised in another thread different than UI thread, so if for any reason you want to do some UI code in the event you should useInvoketo make a thread safe call to a UI element.
○ Putting time-consuming UI tasks in the DoWork is useless. Because the task should be run in UI thread usingInvokeand it will make the UI thread busy again.You can handle
RunWorkerCompletedevent to perform some tasks after the work inDoWorkgot completed. For example after you load data inDoWork, you can use the loaded data inRunWorkerCompletedto fill aComboBox.You should call
RunWorkerAsyncmethod of the component to start processingDoWorkevent.
○ When an async task is running using an instance of the component you can not start another task using the same component, so to prevent exception you should checkthis.backgroundWorker1.IsBusyand if the component is not busy call the method.The component has a good support for error reporting or progress changing or cancelling the execution. To learn more about the features, take a look at documentations.
For .NET 4.5 and later, you can use async/await pattern to perform asynchronous tasks.
Example
I suppose you have a LoadData method currently:
public void LoadData()
{
this.categoryTableAdapter.Fill(this.testDBDataSet.Category);
}
And you want to populate a control with data which you load using LoadData. So you can handle the DoWork and RunWorkerCompleted like this:
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";
}
Also you should call the RunWorkerAsync when you want the task get started, for example:
private void button1_Click(object sender, EventArgs e)
{
if (!this.backgroundWorker1.IsBusy)
this.backgroundWorker1.RunWorkerAsync();
}
来源:https://stackoverflow.com/questions/40473030/background-worker-attempt