简体   繁体   中英

Progress Bar Update In Worker Thread

I'm trying to create a simple progress bar to update using a thread on my form. I can't seem to get the Invoke call to fire on the progress bar, can anyone tell me why?

Here is my very simple form, with just a progress bar and button to execute.

  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();

            }
        }
    }

Try to use the BackgroundWorker instead.

You will be able to report progress mid-work and update your progressbar withouto all the invokationstuff.

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
        }
    }
}

you can use backgorundworker you can read about it in this example

the backgroundWorker_DoWork part:

 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);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM