web-dev-qa-db-ja.com

WPFで進行状況バーをリアルタイムで更新する

進行状況バーに更新をリアルタイムで表示させるのに問題があります。

これは今の私のコードです

for (int i = 0; i < 100; i++)
{
     progressbar1.Value = i;
     Thread.Sleep(100);
}

ただし、何らかの理由で、関数の実行時にプログレスバーに空が表示され、関数の実行が完了するまで何も表示されません。誰かがこれをどのように行うことができるかを私に説明できますか?私はC#/ WPFが初めてなので、この問題を解決するために別のスレッドにDispatcherを実装する方法(他の投稿で見られるように)を100%確信できません。

明確にするために、私のプログラムにはボタンがあり、押すとテキストボックスから値を取得し、APIを使用して情報を取得し、それに基づいてラベルを作成します。すべてのデータ行の処理が終了した後、進行状況バーを更新する必要があります。

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

private async void search(object sender, RoutedEventArgs e)
{
    var progress = new Progress<int>(value => progressbar1.Value = value);
    await Task.Run(() =>
    {
        this.Dispatcher.Invoke((Action)(() =>
        {
             some pre-processing before the actual for loop occur
             for (int i = 0; i < numberofRows; i++)
             {
                  label creation + adding
                  ((IProgress<int>)progress).Report(i);
             }
        }));
    });
}

ありがとうございました!

16
nonion

それを機能させることができた。私がする必要があるのはただそれを作る代わりに

progressBar1.value = i;

しなければならなかった

progressbar1.Dispatcher.Invoke(() => progressbar1.Value = i, DispatcherPriority.Background);
22
nonion

.NET 4.5以降を使用している場合は、 async/await を使用できます。

var progress = new Progress<int>(value => progressBar.Value = value);
await Task.Run(() =>
{
    for (int i = 0; i < 100; i++)
    {
        ((IProgress<int>)progress).Report(i);
        Thread.Sleep(100);
    }
});

asyncキーワードを使用してメソッドをマークし、awaitを使用できるようにする必要があります。次に例を示します。

private async void Button_Click(object sender, RoutedEventArgs e)
27
Aleksey Shubin

.NETに含まれる BackgroundWorker を使用する必要があります。これは、イベントのバックグラウンドスレッドの進行状況を報告するためのメソッドを提供します。 BackGroundWorkerを作成したスレッドは、このイベントを自動的に呼び出します。

BackgroundWorker.ProgressChanged を使用して、非同期操作の進行状況をユーザーに報告できます。

// This event handler updates the progress bar. 
private void backgroundWorker1_ProgressChanged(object sender,
    ProgressChangedEventArgs e)
{
    this.progressBar1.Value = e.ProgressPercentage;
}

これの使用に関する詳細については、MSDNを参照してください。

5