簡體   English   中英

在WPF中使用BackgroundWorker和ProgressBar

[英]Using BackgroundWorker with ProgressBar in WPF

嗨我有一個應用程序,其中一個作業將轉換Excel並將所有記錄傳遞給數據庫。

所以這需要一點時間,因為它將超過7000行,我將獲得並插入到數據庫中。

因為這項工作需要一點時間,超過3分鍾,我想使用ProgressBar來報告這項工作的進展情況。

因此,如果我正在創建我創建的這個Job in Class,那么我如何使用backgroundWorker向我的案例中的progessBar報告進度?

我的目標是准確地了解進展的百分比,以及如何使用所有這些東西來報告進度。 我從未與backgroundWorkers合作過。

我想,這只是一個提示,可能是好的或不是,我首先得到excel中的行數,將該數字作為ProgressBar中的一些Maxvalue,然后對於每一行或在一個間隔中我報告進度。

這個有可能? 我該怎么做?

我喜歡使用ProgressBars的綁定(以及可能的其他所有內容),因為這樣你就不必擔心調度到UI線程了

基本上,您創建了一個實現INotifyPropertyChanged的類,其中包含可以將ProgressBar綁定到的progress屬性。 例如

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更改,例如方法或將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();
}

這是一個有進步后台工作者的例子。

但是,仔細檢查以確保BGW可以在您的情況下工作。 如果您通過COM互操作控制Excel,則可能需要STA線程(並且BGW是MTA線程,而不是STA)。

如果是這種情況,您將需要使用帶有STA調度程序Task ,或您自己的手動Thread (我強烈建議使用基於Task的方法)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM