工作线程中的进度栏​​更新

时间:2015-02-17 14:04:03

标签: c# multithreading winforms visual-studio-2010

我尝试创建一个简单的进度条,使用表单上的线程进行更新。我似乎无法在进度条上触发Invoke调用,有人可以告诉我原因吗?

这是我非常简单的表单,只需要一个进度条和按钮来执行。

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

        //vars
        System.Threading.Thread thr = null;
        bool runProgressBarUpdateThread = false;

        private void button1_Click(object sender, EventArgs e)
        {
            thr = new System.Threading.Thread(ProgressBarUpdateThread);
            thr.Start(this);

            while (true)
            {
                /*lots of work loop here*/

            }
        }

        //Thread To Run To Update The Progress Bar
        public void ProgressBarUpdateThread(object param)
        {
            Form1 frm = param as Form1;

            while (frm.runProgressBarUpdateThread)
            {
                //increase progress bar
                frm.IncProgressBar(1);

                //sleep for half a sec
                System.Threading.Thread.Sleep(500);
            }
        }

        public delegate void IncProgressBarDelegate(int value);

        public void IncProgressBar(int value)
        {
            //need to invoke?
            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new IncProgressBarDelegate(IncProgressBar), value);  //<-- seems to get stuck here
            }
            else
            {
                //update the progress bar value by value or reset to 0 when maximum is reached
                progressBar1.Value = (progressBar1.Value + value >= progressBar1.Maximum) ? progressBar1.Minimum : progressBar1.Value + value;

                progressBar1.Invalidate();
                progressBar1.Update();
                progressBar1.Refresh();

            }
        }
    }

2 个答案:

答案 0 :(得分:1)

尝试使用BackgroundWorker。

您可以在工作中报告进度并更新进度条而无需调用所有内容。

public partial class Form1 : Form
{
    BackgroundWorker bgw;
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        bgw = new BackgroundWorker();
        bgw.DoWork += YourCrazyLoopHere;
        bgw.ProgressChanged += UpdateProgressBar;
        bgw.RunWorkerCompleted += CrazyLoopDone;
        bgw.WorkerReportsProgress = true;
        bgw.RunWorkerAsync();
    }

    private void CrazyLoopDone(object sender, RunWorkerCompletedEventArgs e)
    {
        //finishing up stuff, perhaps hide the bar or something?
        progressBar1.Visible = false;
    }

    private void UpdateProgressBar(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }

    private void YourCrazyLoopHere(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            /*lots of work loop here*/
            bgw.ReportProgress(1);//between 0 and 100
        }
    }
}

答案 1 :(得分:0)

您可以使用backgorundworker来查看this example

中的内容

backgroundWorker_DoWork部分:

 private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        var backgroundWorker = sender as BackgroundWorker;
        for (int j = 0; j < 100000; j++)
        {
            Caluculate(j);
            backgroundWorker.ReportProgress((j * 100) / 100000);
        }
    }