在WPF中使用BackgroundWorker和ProgressBar

本文关键字:BackgroundWorker ProgressBar WPF | 更新日期: 2023-09-27 17:52:38

嗨,我有一个应用程序,其中一个作业将被转换为Excel并将所有记录传递给DB。

所以这需要一点时间,因为我将获得并插入到DB中的行数超过7000行。

所以因为这个作业需要一点时间,超过3分钟,我想使用一个进度条来报告这个作业的进度。

所以,如果我做这个工作在类,我已经创建,我怎么能使用backgroundWorker报告进度到进度栏在我的情况下?

我的目标是准确的进度百分比,以及我如何使用所有这些东西来报告进度。我从来没有和后台工作人员一起工作过。

我认为,这只是一个提示,也许好或不好,我首先得到excel中的行数,使该数字作为ProgressBar中的一些最大值,然后为每一行或在间隔内报告进度。

这可能吗?我该怎么做呢?

在WPF中使用BackgroundWorker和ProgressBar

我喜欢为ProgressBars使用绑定(以及几乎所有其他可能的东西),因为这样你就不需要担心调度到UI线程。

基本上你创建一些类实现INotifyPropertyChanged与一个进度属性,你可以绑定你的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();
}

下面是一个带有progress的后台worker的例子。

但是,请仔细检查以确保BGW在您的情况下有效。如果你通过COM互操作来控制Excel,它可能需要一个STA线程(BGW是一个MTA线程,而不是STA)。

如果是这种情况,您将需要使用带有STA调度器的Task,或者您自己的手动Thread(我强烈建议使用基于Task的方法)。

相关文章:
  • 没有找到相关文章