バックグラウンドワーカーが実際にどのように機能するかについて質問があります。さまざまな方法でどのように機能するかはよくわかりません。
たとえば、次のコードがあります (説明のためにhttp://broadcast.oreilly.com/2010/06/understanding-c-using-backgrou.htmlから適応):
private void getDateTime()
{
DateTime startTime = DateTime.Now;
double value = Math.E;
while (DateTime.Now < startTime.AddMilliseconds(100))
{
value /= Math.PI;
value *= Math.Sqrt(2);
}
}
private backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for(int i=0; i <= 100; i++)
{
getDateTime();
backgroundWorker1.ReportProgress(i);
}
}
これにより、backgroundworker スレッドを使用して DateTime が継続的に計算されます。ここで、バックグラウンド ワーカーの DoWork メソッド内の for ループが計算を実行し、進行状況を報告し、ループを繰り返すと想定しています (誤解していた場合は訂正してください)。
(おそらく大きな)DataTableを解析して別のDataTableを返す別のメソッドがあると仮定すると、バックグラウンドワーカーでそれを使用すると、DataTableを何度も解析することになります(理論的には、間違っている場合は修正してください) ? これがプログラムの流れである場合、ループを繰り返すことなく DataTable の解析を達成するためのより効率的な方法はありますか?
これは Windows フォームを対象としており、DataTable を解析すると UI がフリーズする傾向があります。backgroundworker が UI のフリーズを回避するのに役立つと聞いたことがありますが、DataTable 全体を何度も再解析しなければならないのは非常に非効率的です。ただし、for ループなしで進行状況を報告できる他の方法もわかりません。
編集:
私は一時的な解決策を見つけました。動作しますが、進捗状況を報告する方法がまだありません。
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int rows = (int)e.Argument;
int count = 0;
t3 = runComparison();
for (int i = 0; i <= rows; i++)
{
count++;
int current = count / rows;
backgroundWorker1.ReportProgress(current * 100);
}
e.Result = t3;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show("An unexpected error has occurred. Please try again later.", "ERROR!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
dataGridView1.DataSource = e.Result;
}
}
for ループが何もしないことはわかっています。ただし、「runComparison」はすでに多くの時間を消費しています。そのため、for ループ内にある場合、進行状況は実行全体が報告されるまで報告されません。または、プログレス バーの代わりにラベルまたはメッセージ ボックスを使用することもできます。どうすればこれを達成できるのかよくわかりません。