c# progressbar не обновляющий

У меня есть ProgressBarWindow, который имеет progressbar и кнопку отмены на нем, которую я использую для создания отчетов о достижениях по файловому вводу-выводу. Однако Поток UI 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 (остальное - просто несколько методов set):

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;
        }
    }
} 

Я попытался перенести строку метода set значения в делегата dispatcher.invoke, но это дает мне переполнение стека (у меня не придется быть dispatcher.invoke строки так или иначе, как backgroundworker называет ProgressChanged в Потоке UI, правильно?). Я проверил MSDN и погуглил, но я, может казаться, не нахожу никого больше с этой проблемой.

Извинения РЕДАКТИРОВАНИЯ, я не понял, что мой упрощенный код заблокировал Поток UI, я получаю точно то же поведение несмотря на использование backgroundworker, таким образом, я ошибочно предположил, что они были эквивалентны. Я должен был упомянуть, что использовал backgroundworker :P

8
задан CalumMcCall 2 August 2010 в 11:20
поделиться

2 ответа

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

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

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

РЕДАКТИРОВАТЬ: Хорошо, теперь вы изменили код, мне он кажется нормальным. Он должен быть потокобезопасным, поскольку вы изменяете пользовательский интерфейс только в потоке пользовательского интерфейса. Ваш фоновый работник определенно периодически сообщает о прогрессе?

15
ответ дан 5 December 2019 в 09:23
поделиться

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

3
ответ дан 5 December 2019 в 09:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: