2017-03-29 7 views
0

私はbackgroundworkerの問題を抱えています。私はスレッディングに慣れていないので、できるだけ痛みを伴わずにこれをやろうとしています。C#backgroundworkerのアドバイス

私の主な問題は、エンドユーザーが.NET 4.0しか持たないため、await/asyncを使用できないため、BGWが私が使用しているフレームワークにとって最善のことだと言われました。

私は、DataGridviewが読み込まれている間に読み込みたいGIFアニメーションの「Please Wait」フォームを持っています。私はどういうわけか、「Please Wait」を閉じるために入力を完了したことを確認するためにチェックを行う必要がありますが、これを達成する方法についてちょっと固まっています。

public void btnSearch_Click(object sender, EventArgs e) 
    { 
     backgroundWorker1.RunWorkerAsync(); 
     Application.DoEvents(); 
     try 
     { 
      this.TestDataTableAdapter.Fill(this.TesteDataData.TestDataTable, txtHotName.Text, ((System.DateTime)(System.Convert.ChangeType(txtDepartFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtDepartTo.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime))))); 
      int RowC = TestDataTableDataGridView.RowCount; 
      if (RowC == 0) 
      { 
       MessageBox.Show(GlobVar.NoResults, "", MessageBoxButtons.OK, MessageBoxIcon.Hand); 
      } 
     } 
     catch (System.Exception exc) 
     { 
      MessageBox.Show 
       (
       "Problem" + 
       exc.Message, "An error has occured", MessageBoxButtons.OK, MessageBoxIcon.Warning 
       ); 
     } 
     finally 
     { 
      //pleaseWait.Close(); 
     } 

これは、データをDataGridViewに読み込むためのボタンです。そして、これまでのところ、これはfinallyが原因クロススレッドに動作しません(これは現在コメントアウト)が、私はループを実行する必要があり

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     pleaseWait.ShowDialog(); 
    } 

/DataGridViewのが充填され、行動されているかどうかを確認するためにチェックし、私DoWorkイベントです完了してDoWorkを閉じます。またはいくつかの方法をRunWorkerCompletedにジャンプして強制的に私は代わりにpleaseWait.Close();を置くことができます。

お願いします。

+0

タスクの最後にイベントを撮影するのはどうですか? –

+1

'backgroundWorker1.DoWork'ではなく、メインのuiスレッドに' pleaseWait'ダイアログを表示し、 'backgroundWorker1'の' RunWorkerCompleted'イベントで非表示にする必要があります。 'this.TestDataTableAdapter.Fill'パーツは' backgroundWorker1.DoWork'に入っていますか – Pikoh

答えて

1

あなたのメインUIスレッドでは、ないbackgroundWorker1.DoWorkであなたのpleaseWaitダイアログを表示し、backgroundWorker1RunWorkerCompletedイベントでそれを隠す必要があります。あなたは問題がある、このコードでは、もちろん

public void btnSearch_Click(object sender, EventArgs e) 
{ 
    pleaseWait.ShowDialog(); 
    backgroundWorker1.RunWorkerAsync(); 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     this.TestDataTableAdapter.Fill(this.TesteDataData.TestDataTable, txtHotName.Text, ((System.DateTime)(System.Convert.ChangeType(txtDepartFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtDepartTo.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime))))); 

    } 
    catch (System.Exception exc) 
    { 
     //You can't show a messagebox here,as it is not in the UI thread 
    } 
} 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    pleaseWait.Close(); 
    int RowC = TestDataTableDataGridView.RowCount; 
    if (RowC == 0) 
    { 
      MessageBox.Show(GlobVar.NoResults, "", MessageBoxButtons.OK, MessageBoxIcon.Hand); 
    } 
} 

として、:あなたのコードは、多かれ少なかれ、このようになりますので、this.TestDataTableAdapter.Fill部分は、backgroundWorker1.DoWorkに行くべきものですTestDataTableAdapter.FillTextBoxesにアクセスしようとしていて、別のスレッドからアクセスできないため、コードが機能しません。

これにはいくつか解決策があります。 backgroundworkerを呼び出す前にいくつかの変数を使用して値を読み込み、TextBoxesの代わりにこの変数にアクセスすることができます。あるいは、パラメータを使ってバックグラウンドワーカーに電話することもできます。

について詳しくは、MSDNをお読みください。またはthis questionについては、BackgroundWorkerにパラメータを送信してください。

+0

ありがとうございました。私はBGWを呼び出す前に変数を渡す方法を読むことを試みます。 – Zoltan

関連する問題