WPF - ProgressBar Обновления только до завершения процесса - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь использовать ProgressBar, который является новым для меня (возможно только асинхронное?)

Я следовал WPF-Tutorial и не встретил никаких проблем. Я просто поместил код здесь снова для удобства.

public partial class ProgressBarTaskOnWorkerThread : Window
{
    public ProgressBarTaskOnWorkerThread()
    {
        InitializeComponent();
    }

    private void Window_ContentRendered(object sender, EventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.DoWork += worker_DoWork;
        worker.ProgressChanged += worker_ProgressChanged;

        worker.RunWorkerAsync();
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        for(int i = 0; i < 100; i++)
        {
            (sender as BackgroundWorker).ReportProgress(i);
            Thread.Sleep(100);
        }
    }

    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        pbStatus.Value = e.ProgressPercentage;
    }
}

Так что я просто взял и использовал этот код, и с ним проблем нет. Теперь я пытаюсь использовать его в своем коде и просто изменил функцию worker_DoWork следующим образом:

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        while (this.ValueProgress < 100)
        {
            (sender as BackgroundWorker).ReportProgress(this.valueProgress);
            Thread.Sleep(200);
        }
    }

В своем коде я импортирую список файлов, поэтому я установил this.ValueProgress в 0затем каждый раз, когда я импортирую файл, я делаю это. ValueProgress = 100 * NumberImportedFiles / TotalFiles;

Я также заметил в отладке, что моя функция worker_ProgressChanged не работает во время импорта (но worker_DoWorkработает нормально). Тогда, только когда все файлы импортированы, worker_ProgressChanged запускается много раз (кажется, что он просто запускает все изменения, которые были сделаны сразу).

Редактировать: Просто сделал еще один "глупый" тест:

Я сохранил исходный код, добавив условие, поэтому ProgressBar начнет двигаться после того, как я отредактирую ValueProgress:

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < 100; i++)
    {
        if(this.ValueProgress==0)
        {
            i--;
        }
        (sender as BackgroundWorker).ReportProgress(i);
        Thread.Sleep(100);
    }
}

И этот код не работает, я имею в виду функцию worker_DoWork работает правильно, я начинаю увеличиваться после начала процесса, но ProgressBar не двигается (worker_ProgressChanged не запускается).

Ответы [ 2 ]

1 голос
/ 25 октября 2019

У меня нет репутации, чтобы комментировать, поэтому я публикую ответ. Если некоторые из моих предположений ошибочны, я заранее прошу прощения. Где вы устанавливаете значение ValueProgress? Если вы устанавливаете значение ValueProgress в потоке пользовательского интерфейса вместо использования фоновой работы, возможно, вы задерживаете поток пользовательского интерфейса.

Если это так, то любые обновления индикатора выполнения не будут отображаться. вверх. Попробуйте выполнить какие-либо обновления в фоновом режиме, чтобы пользовательский интерфейс мог обновляться.

Вот учебник , который поможет решить проблему

0 голосов
/ 25 октября 2019

Вы можете попытаться обновить ProgressBar в главном потоке.

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    Application.Current.Dispatcher.Invoke(() => pbStatus.Value = e.ProgressPercentage);
}

Проблема в том, что обновление пользовательского интерфейса в другом потоке не будет работать. Может только основная нить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...