ProgressBar表单挂在中间,从BackGroundWorker类更新的值

时间:2014-07-24 03:43:21

标签: c# winforms class progress-bar backgroundworker

我创建了一个带有button1的form1来启动任务,该任务将在背景上使用BackGroundWorker在单独的类上进行处理,并在单独的窗口中显示ProgressBar。

我的问题是这个过程工作正常,但是任务完成但是进度条表格挂在中间。

enter image description here

下面是BackGroundLoading Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.ComponentModel;

namespace sample2
{
    public class BackgroundLoading
    {
        public BackgroundWorker Bw;
        public delegate void RunFunction();
        public RunFunction thisFunction;
        mycontrols.LoadProgress p = new mycontrols.LoadProgress();

        public BackgroundLoading(RunFunction newFunction)
        {
            thisFunction = newFunction;
            Bw = new BackgroundWorker();
            Bw.WorkerReportsProgress = true;
            Bw.DoWork += new DoWorkEventHandler(Bw_DoWork);
            Bw.ProgressChanged += new ProgressChangedEventHandler(Bw_ProgressChanged);
            Bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Bw_RunWorkerCompleted);
        }

        public void Start()
        {
            Bw.RunWorkerAsync();
        }

        void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show("Error: " + e.Error.Message);
            }
            if (e.Cancelled)
            {
                MessageBox.Show("Cancelled!");
            }
            else
            {
                MessageBox.Show("Completed!");
                p.Close();
            }

        }

        public void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            /// If I put 
            /// p.ProgBar.Value = e.ProgressPercentage;
            /// the progressbar hangs upon form show.
        }

        void Bw_DoWork(object sender, DoWorkEventArgs e)
        {
            p.Show();

            BackgroundWorker worker = sender as BackgroundWorker;

            for (int i = 1; (i <= 100); i++)
            {
                if ((worker.CancellationPending == true))
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    if (thisFunction != null)
                    {
                        thisFunction();
                        worker.ReportProgress((i * 1));
                        p.ProgBar.Value = i;   
                    }
                    else
                    {
                        MessageBox.Show("Error, no method found");
                    }
                }
            }

        }
    }
}

这是Form1代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace sample2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            BackgroundLoading BL = new BackgroundLoading(workingmethod);
            BL.Start();
        }

        private void workingmethod()
        {
            System.Threading.Thread.Sleep(10);
        }

    }
}

这是LoadProgress表单的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace sample2.mycontrols
{
    public partial class LoadProgress : Form
    {
        public LoadProgress()
        {
            InitializeComponent();
        }

        private void LoadProgress_Load(object sender, EventArgs e)
        {     

        }

    }
}

自从在类上完成更新后,进度条表单上没有代码。 找不到悬挂的原因。

先谢谢。

1 个答案:

答案 0 :(得分:1)

在运行BackgroundWorker

之前,在主UI线程上显示表单
public void Start()
{
    p.Show();

    Bw.RunWorkerAsync();
}

然后,您可以调用ProgressChanged事件中的表单,该事件在UI线程上运行。

p.Show()事件中删除p.ProgBar.Value = i;DoWork - 您不想从后台线程触摸UI线程。

public void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    p.ProgBar.Value = e.ProgressPercentage;
}

最后,在BackgroundWorker完成后(您已经在做),关闭表单:

void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    p.Close();
}