主要是使用BackgroundWorker控件实现异步刷新……

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class ProgressTool
{
    private BackgroundWorker backgroundWorkerProgress;

    public ProgressTool()
    {
        // 
        // backgroundWorkerProgress
        // 
        this.backgroundWorkerProgress = new System.ComponentModel.BackgroundWorker();
        this.backgroundWorkerProgress.WorkerReportsProgress = true;
        this.backgroundWorkerProgress.WorkerSupportsCancellation = true;
        this.backgroundWorkerProgress.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorkerProgress_DoWork);
        this.backgroundWorkerProgress.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorkerProgress_RunWorkerCompleted);
    }

    public void StartBar(Form dialog, int maxVal)
    {
        // 为了开始在后台操作,必须调用BackgroundWorker的RunWorkerAsync()方法,当调用此方时,BackgroundWorker 通过触发DoWork 事件,开始执行后台操作,DoWork 事件的代码是在另一个线程里执行的。
        if (this.backgroundWorkerProgress.IsBusy)
            return;
        this.backgroundWorkerProgress.RunWorkerAsync(maxVal);

        // 显示进度条窗体 
        FormProgress form = new FormProgress(this.backgroundWorkerProgress);
        form.ShowDialog(dialog);
        form.Close();
    }

    public Func<int, string> BackgroundFunc = null;
    private void backgroundWorkerProgress_DoWork(object sender, DoWorkEventArgs e)
    {
        int maxval = Convert.ToInt32(e.Argument);

        BackgroundWorker worker = sender as BackgroundWorker;
        for (int i = 0; i < maxval; i++)
        {
            if (this.BackgroundFunc != null)
            {
                string strShow = BackgroundFunc(i);

                // 注意:这里向子窗体返回信息值,这里是两个值,一个用于进度条,一个用于文本框的。
                worker.ReportProgress((int)(i * 100.0f / maxval), strShow + "\r\n");
            }

            // 如果用户取消则跳出处理数据代码 
            if (worker.CancellationPending)
            {
                // 利用CancellationPending 属性,可以判断是否取消后台异步操作。
                e.Cancel = true;
                break;
            }
        }
        // 在执行DoWork 事件时,DoWorkEventArgs 实例的Result 属性,返回值到用户;在RunWorkerCompleted 事件里,RunWorkerCompletedEventArgs 实例的Result 属性接收值;
    }

    private void backgroundWorkerProgress_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // 当后台操作完成以后,无论是completed 还是cancelled,RunWorkerCompleted 事件被触发,通过此方法可以将后台操作的完成结果反馈给用户;
        // 另外,通过RunWorkerCompletedEventArgs实例的Cancelled 属性,以判断是否是Cancel操作使得后台操作终止;
        if (e.Error != null)
        {
            MessageBox.Show("发生异常错误 -> " + e.Error.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        else if (e.Cancelled)
        {
            MessageBox.Show("用户取消", "已取消", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        else
        {
            // 执行完成
        }
    }
}

public partial class FormProgress : Form
{
    //ProcessForm 窗体事件(进度条窗体)
    private BackgroundWorker backgroundWorkerBar = null; 
    public FormProgress(BackgroundWorker backWorker)
    {
        InitializeComponent();

        this.backgroundWorkerBar = backWorker;
        this.backgroundWorkerBar.ProgressChanged += new ProgressChangedEventHandler(backgroundWorkerBar_ProgressChanged);
        this.backgroundWorkerBar.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerBar_RunWorkerCompleted);
    }

    private void backgroundWorkerBar_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // 为了显示后台操作的执行进度,首先要使WorkerReportsProgress 等于true,然后调用BackgroundWorker的ReportProgress()方法,通过它传递操作完成的进度值
        // 此外,该方法触发ProgressChanged事件,在是此事件中,通过ProgressChangedEventArgs的实例,接收到主线程传递过来的参数。
        this.progressBarShow.Value = e.ProgressPercentage;
        //主窗体传过来的值,通过e.UserState.ToString()来接受
        this.textBoxBar.AppendText(e.UserState.ToString());
    }

    private void backgroundWorkerBar_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //执行完之后,直接关闭页面
        this.Close();
    }

    private void buttonCancel_Click(object sender, EventArgs e)
    {
        // 为了使 BackgroundWorker 可以取消后台正在执行的操作,首先要把属性WorkerSupportsCancellation 的值设置为 true。
        // 接着调用CancelAsync()方法,该方法使得属性CancellationPending 为true,
        this.backgroundWorkerBar.CancelAsync();
        this.buttonCancel.Enabled = false;
        this.Close();
    }
}