c# progressbar не обновляется

У меня есть ProgressBarWindow, который имеет progressbar и кнопку отмены на нем, который я использую для отчета о прогрессе в файле ввода-вывода. однако поток пользовательского интерфейса ProgressBarWindow и мое главное окно оба висят, несмотря на всю работу, выполняемую в backgroundworker. Progressbar отображается, как и мое главное окно, но не обновляется, пока backgroundworker делает свое дело. Следующий код вызывается в самом конце конструктора, главного окно:

iCountLogLinesProgressBar = new ProgressBarWindow();
iCountLogLinesProgressBar.cancelButton.Click += EventCountLogLinesProgressBarCancelButtonClicked;
iCountLogLinesProgressBar.Show();

iCountLogRecords = new BackgroundWorker();
iCountLogRecords.DoWork += EventCountLogLinesDoWork;
iCountLogRecords.ProgressChanged += EventCountLogLinesProgressChanged;
iCountLogRecords.RunWorkerCompleted += EventCountLogLinesRunWorkerCompleted;
iCountLogRecords.WorkerReportsProgress = true;
iCountLogRecords.WorkerSupportsCancellation = true;
iCountLogRecords.RunWorkerAsync(new BinaryReader(File.Open(iMainLogFilename, FileMode.Open, FileAccess.Read)));

EventCountLogLinesProgressChanged () выглядит следующим образом:

private void EventCountLogLinesProgressChanged(object sender, ProgressChangedEventArgs e)
{
    iCountLogLinesProgressBar.Value = e.ProgressPercentage;
}

вот сокращенная версия ProgressBarWindow (остальное - всего лишь пара сеттеров):

public partial class ProgressBarWindow : Window
{
    public ProgressBarWindow()
    {
        InitializeComponent();
        this.progressBar.Value = this.progressBar.Minimum = 0;
        this.progressBar.Maximum = 100;
    }

    public double Value
    {
        get
        {
            return progressBar.Value;
        }
        set
        {
            this.progressBar.Value = value;
        }
    }
} 

Я попытался обернуть строку задатчика значений в диспетчер.вызовите делегат, но это дает мне переполнение стека (мне не нужен диспетчер.вызовите строку в любом случае, как backgroundworker вызывает ProgressChanged в потоке пользовательского интерфейса, верно?). Я проверил msdn и googled но я не могу найти никого с этой проблемой.

редактировать извинения, я не понял, что мой упрощенный код заблокировал поток пользовательского интерфейса, я получаю точно такое же поведение, несмотря на использование backgroundworker, поэтому я ошибочно предположил, что они эквивалентны. Я должен был упомянуть, что использую backgroundworker: P

2 ответов


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

переместите фоновую обработку в отдельный поток и используйте соответствующий Dispatcher вызовов (или BackgroundWorker) для маршалирования UI update вызывает обратно в поток UI.

Если ваш индикатор прогресса действительно просто хотел быть таймером, вы можете использовать один из Timer классы для его обновления.

EDIT: хорошо, теперь вы изменили код, он выглядит нормально для меня. Он должен быть потокобезопасным, поскольку вы только меняете пользовательский интерфейс в потоке пользовательского интерфейса. Ваш фоновый работник определенно периодически сообщает о прогрессе?


слушайте Джона Скита, или вы можете иногда позвонить в приложение.DoEvents (), чтобы сделать все обновления пользовательского интерфейса в одном потоке.