2016-11-08 119 views
0

这是我后台工作的DoWor功能,是否考虑到GUI操作的执行情况好吗?后台工作人员执行

 private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
    { 
     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.Invoke((MethodInvoker)delegate 
       { 
        comboBox2.Items.Add(scode); 
       }); 
       } 
     } 
     catch (Exception ex) 
     { 

      MessageBox.Show(ex.ToString()); 
     } 
    } 

这是调用它的功能:

private void comboBox4_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if(comboBox4.SelectedIndex == 0) 
     { 
      backgroundWorker1.RunWorkerAsync(); 

     } 
     else 
     { 

      MessageBox.Show("This table doesn't exist within the database"); 
     } 
    } 

目前没有happens..the代码只是在屏幕上的默认形式运行。不加载值,我做错了什么?

+0

我想你会做你的代码工作通过调用'backgroundWorker1.RunWorkerAsync();'直接使用一个按钮。但是你的背景工作者是无用的,因为你在'DoWork'事件中做了一个沉重的UI任务。 –

+0

但我认为使用方法调用者会帮助 – Jevon

+0

不,它不会帮助。当你使用'Invoke'时,你传递给它的动作将在UI线程中运行。 –

回答

3

BGW已过时。 TPL,async/awaitIProgress<T>可以解决使用BGW的所有情况和更多情况。

在这种情况下,BGW并不适合。真正的延迟是由数据库调用造成的,而不是加载UI。异步执行数据库调用,您只需要使用异步事件处理程序:

private async void comboBox4_SelectedIndexChanged(object sender, EventArgs e) 
{ 
     var conString=Properties.Settings.Default.MyConnectionString; 
     string query = "SELECT * FROM dbo.Liguanea_Lane2";      

     using(var con = new SqlConnection(conString)) 
     using(var cmd = new SqlCommand(query, con)) 
     { 
      await con.OpenAsync(); 
      var reader=await cmd.ExecuteReader(); 
      while (dr.Read()) 
      { 
       string scode = dr.GetString(dr.GetOrdinal("code")); 
       comboBox2.Items.Add(scode); 
      } 
     } 
} 

有更好的方式来加载,虽然一个组合。一个改进是加载列表中的所有项目,然后使用AddRange更新组合。 AddRange已经调用了BeginUpdate来防止UI更新,同时添加列表中的项目。

 var items=new List<string>(); 
     using(var con = new SqlConnection(conString)) 
     using(var cmd = new SqlCommand(query, con)) 
     { 
      await con.OpenAsync(); 
      var reader=await cmd.ExecuteReader(); 
      while (dr.Read()) 
      { 
       string scode = dr.GetString(dr.GetOrdinal("code")); 
       list.Add(scode); 
      } 
     } 

     comboBox2.Items.AddRange(items); 

更妙的是,使用微型ORM喜欢小巧玲珑摆脱所有这些代码:

using(var con = new SqlConnection(conString)) 
{ 
    await con.OpenAsync(); 
    var items=await con.QueryAsync<string>(query); 
    comboBox2.Items.AddRange(items); 
} 
+0

有没有办法包含一个进度条来跟踪加载过程?我不确定它是否会很快加载20k记录,或者可能只是给用户一个加载屏幕来看 – Jevon

+0

@Jevon当然,异步/等待只是在循环中放置一个栏并根据需要进行更新。你仍然在UI线程中,所以你可以这样做,就像你将项目添加到组合框一样。做酒吧最难的部分是有效地获得要处理的项目总数。 –

+0

@ScottChamberlain谢谢,我会努力的。 :) – Jevon