Использование BackgroundWorker с ProgressBar в WPF - PullRequest
3 голосов
/ 25 апреля 2011

Привет, у меня есть приложение, в котором одно из заданий будет конвертировать Excel и передавать все записи в БД.

Так что это займет немного времени, потому что я получу более 7000 строк ивставить в базу данных.

Так как эта работа занимает немного времени, более 3 минут, я бы хотел использовать ProgressBar для отчета о ходе выполнения этой работы.

Так что если явыполняя эту работу в классе, которую я создал, как я могу использовать backgroundWorker, чтобы сообщить о прогрессе в progessBar в моем случае?

Моя цель - быть точным в процентах того, как продвигается прогресс, и какЯ могу использовать все эти вещи, чтобы сообщить о прогрессе.Я никогда не работал с backgroundWorkers.

Я думаю, и это только подсказка, может быть, хорошая или нет, что я сначала получаю количество строк в Excel, делаю это число как некоторое Maxvalue в ProgressBar,и затем для каждой строки или в интервале я сообщаю о прогрессе.

Это возможно?Как я могу это сделать?

Ответы [ 2 ]

4 голосов
/ 25 апреля 2011

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

По сути, вы создаете некоторый класс, который реализует INotifyPropertyChanged со свойством progress, с которым вы можете связать свой ProgressBar. например,

public class Task : INotifyPropertyChanged
{
    private int _progress = 0;
    public int Progress
    {
        get { return _progress; }
        private set
        {
            if (_progress != value)
            {
                _progress = value;
                OnPropertyChanged("Progress");
            }
        }
    }

    public Task(ref ProgressChangedEventHandler progressChangedEvent)
    {
        progressChangedEvent += (s, e) => Progress = e.ProgressPercentage;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Этот класс использует в конструкторе событие, которое будет обновлять ход выполнения задачи, если оно поднято, но вы можете обрабатывать изменение хода выполнения любым удобным для вас способом, например. метод или сделав свойство Progress public, чтобы вы могли просто произвольно изменить его.


Пример использования:

<ProgressBar Minimum="0" Maximum="100" Height="20"
             Value="{Binding UpdateTask.Progress, Mode=OneWay}"/>
// The event that should be raised when a progress occurs.
private event ProgressChangedEventHandler UpdateProgressChanged;

// The task the ProgressBar binds to.
private readonly Task _updateTask;
public Task UpdateTask
{
    get { return _updateTask; }
}

public MainWindow()
{
    // Instatiate task, hooking it up to the update event.
    _updateTask = new Task(ref UpdateProgressChanged);
}

private void OnUpdateProgressChanged(int progressPercentage)
{
    if (UpdateProgressChanged != null)
    {
        UpdateProgressChanged(this, new ProgressChangedEventArgs(progressPercentage, null));
    }
}

// Simple progress simulation
private void Button1_Click(object sender, RoutedEventArgs e)
{
    int progress = 0;
    DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(0.5) };
    timer.Tick += (sSub,eSub) =>
    {
        progress++;
        // Raise progress changed event which in turn will change
        // the progress of the task which in turn will cause
        // the binding to update which in turn causes the value
        // of the ProgressBar to change.
        OnUpdateProgressChanged(progress);
        if (progress == 100)
        {
            timer.Stop();
        }
    };
    timer.Start();
}
0 голосов
/ 25 апреля 2011

Вот пример фонового работника с прогрессом .

Тем не менее, проверьте еще раз, чтобы убедиться, что BGW будет работать в вашей ситуации. Если вы управляете Excel через COM-взаимодействие, для этого может потребоваться поток STA (а BGW - это поток MTA, а не STA).

Если это так, вам нужно использовать Task с STA планировщиком или ваше собственное руководство Thread (я настоятельно рекомендую подход, основанный на Task).

...