简体   繁体   中英

C# Filling progress bar in separate thread

I have a progress bar and want to fill it in using a separate thread, because the main thread is put to sleep for a few seconds in a loop. I'm using a timer so that the progress bar fills up over a certain amount of time.

Thread creation:

private void PlayButton_Click(object sender, EventArgs e)
        {
            progressBar1.Value = 0;
            int playTime = getPlayTime();
            int progressInterval = playTime / 100;
            Thread progressThread = new Thread(barfiller=>fillBar(progressInterval));
            progressThread.Start();

            //Loops through the collection and plays each note one after the other
            foreach (MusicNote music in this.staff.Notes)
            {
                music.Play(music.Dur);
                Thread.Sleep(music.getInterval(music.Dur));
            }
            progressThread.Abort();
        }

As is, nothing happens to the progress bar, if however I call fillbar() within the main thread, it works BUT it fills after the for loop is complete and not before/during the for loop even though I call fillbar() before the loop.

Thread methods:

private void fillBar(int progressInterval)
        {
            progressTimer = new System.Windows.Forms.Timer();
            progressTimer.Tick += new EventHandler(clockTick);
            progressTimer.Interval = progressInterval; //How fast every percentage point of completion needs to be added
            progressTimer.Start();

        }

        public void clockTick(object sender, EventArgs e)
        {
            if (progressBar1.Value < 100)
            {
                progressBar1.Value++;
            }
            else
            {
                progressTimer.Stop();
            }

        }

You're doing it the wrong way. The main thread is reponsible of updating the user interface. So if you're blocking it with your calculations, it won't be able to draw the progress bar. Move your computing code in another thread and it should be fine.

always the main thread for manage user interface. use backgroundworker for this purpose. to enable progress feature in backgroundworker set WorkerReportProgress(property) to true and set WorkerSupportCancellation for stopping backgroundworker if needed.

  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
         // also use sender as backgroundworker
        int i = 0;
        foreach (MusicNote music in this.staff.Notes)
        {
            if(backgroundWorker1.CancellationPending) return;
             music.Play(music.Dur);
            Thread.Sleep(music.getInterval(music.Dur));

            int p =  (int) (i*100/ staff.Notes.Count); /*Count or Length */
            backgroundWorker1.ReportProgress(p);
            i++;
        }
        backgroundWorker1.ReportProgress(100);
    }

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

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