2016-11-08 7 views
0

これは私のバックグラウンドの仕事DoWor関数です。バックグラウンドワーカーの実装

 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()'を呼び出すことによって、私はあなたが作業してコードを作るとしますDapperのは、このすべてのコードを取り除くために同じよう

 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を使用しますボタンを使用してしかし、あなたのバックグラウンドワーカーは、DoWorkイベントで重いUIタスクを実行しているので、何とか役に立たない。 –

+0

しかし、私はInvokerメソッドを使って助けてくれると思った。 – Jevon

+0

いいえ、役に立たないでしょう。 'Invoke'を使うと、渡すアクションはUIスレッドで実行されます。 –

答えて

3

BGWは廃止さ​​れました。 TPL、async/awaitおよびIProgress<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); 
      } 
     } 
} 

しかしコンボをロードするためのより良い方法があります。 1つの改善点は、リスト内のすべての項目をロードし、次にAddRangeを使用してコンボを更新することです。 AddRangeは既にリストからアイテムを追加している間、UI更新を防ぐためにBeginUpdateを呼び出します。 ;直接 `

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を見るための読み込み画面を与えるだけです。async/awaitはループにバーを置き、必要に応じて更新します。コンボボックスにアイテムを追加するのと同じように、あなたはUIスレッド上にいます。バーを実行するのが最も難しいのは、処理するアイテムの総数を効率的に取得することです。 –

+0

@ScottChamberlainありがとう、私はそれに取り組んでいます。 :) – Jevon

関連する問題