web-dev-qa-db-ja.com

Backgroundworkerは進捗状況を報告しません

長いデータベースタスクを実行しているバックグラウンドワーカーがいます。タスクの実行中にプログレスバーを表示したい。どういうわけか、バックグラウンドワーカーはタスクの進行状況を報告しません。

これは私が持っているものです:

BackgroundWorker _bgwLoadClients;

_bgwLoadClients = new BackgroundWorker();
_bgwLoadClients.WorkerReportsProgress = true;
_bgwLoadClients.DoWork += new DoWorkEventHandler(_bgwLoadClients_DoWork);
_bgwLoadClients.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgwLoadClients_RunWorkerCompleted);
_bgwLoadClients.ProgressChanged += new ProgressChangedEventHandler(_bgwLoadClients_ProgressChanged);
_bgwLoadClients.RunWorkerAsync(parms);

private void _bgwLoadClients_DoWork(object sender, DoWorkEventArgs e)
{
    DataTable dt = getdate();
    e.Result = dt;
}

void _bgwLoadClients_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

私はこれをWPFで行っていますが、違いはないと思います。

前もって感謝します

18
Angela

DoWorkメソッドをレポート可能な進行状況に分解してから、ReportProgressを呼び出す必要があります。

たとえば、次のようにします。

private void Something_DoWork(object sender, DoWorkEventArgs e) 
{
    // If possible, establish how much there is to do
    int totalSteps = EstablishWorkload();

    for ( int i=0; i<totalSteps; i++)
    {
        // Do something...

        // Report progress, hint: sender is your worker
        (sender as BackgroundWorker).ReportProgress((int)(100/totalSteps)*i, null);
    }

}

作業を事前に決定できない場合は、独自のパーセンテージを追加してみてください。

private void Something_DoWork(object sender, DoWorkEventArgs e) 
{
    // some work

    (sender as BackgroundWorker).ReportProgress(25, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(50, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(60, null);

    // some work

    (sender as BackgroundWorker).ReportProgress(99, null);
}
31
Ray Hayes

プロパティウィンドウまたはコードのいずれかで、backgroundworkerオブジェクトのWorkReportProgressプロパティをtrueに変更します。

10
prem

ProgressChanged イベントを発生させるには、手動で ReportProgress() を呼び出す必要があります。

3

DoWorkメソッドでworker.ReportProgress(percentComplete)を呼び出す必要があります。パーセント完了は、総作業量に基づいて計算する必要があります。例えば:

for(int i =0; i != 100; i++) {
    // do something
    worker.ReportProgress(i);
}

進行状況を報告できるように、ジョブをいくつかのチャンクに分割することが難しい場合があります。残念ながら、BackgroundWorkerはこれを解決しません。自分で解決する必要があります。

3
Aleris

doworkイベントの進捗状況を報告するだけです

private void _bgwLoadClients_DoWork(object sender, DoWorkEventArgs e) {
    int progresValue0to100 = 75;
    (sender as System.ComponentModel.BackgroundWorker).ReportProgress(progresValue0to100);
    //do your jobs..
}

それはこのように動作します

2

進行状況は、BackgroundWorkerのReportProgressメソッドを呼び出して、DoWorkイベント内から送信する必要があります。あなたの場合、すべての作業はDoWork関数の外部で行われているため、進行状況を報告することはできません。 getdate()の呼び出しの前後でのみ進行状況を報告できますが、BackgroundWorkerスレッドがビジーであるため、呼び出し中は報告できません。

2
Adam Ruth