簡體   English   中英

后台工作人員的怪異行為和多個進度條C#

[英]Weird behavior of Background worker and multiple progress bar c#

我嘗試模擬一個長時間運行的過程。 在我的應用程序中,我使用背景並動態添加進度欄。 當我單擊開始按鈕時,過程開始,面板上添加了進度條。 如果我只單擊一次,則一切正常,但如果我單擊兩次或多次,則添加的進度條數量會增加,但最后的進度條進度會增加,最后其他進度條的進度會突然增加。

我想要添加任何數量的進度條,所有這些都應同時處理,而不是最后一個和最后一個。 就像許多進程在各自的上下文中同時運行一樣,所有這些都應該在一起。 這是我的代碼,我希望如果有人看一下它,那么他們可以理解缺陷所在。 請幫助我修復最后添加的進度條進度增加的漏洞。 如果可能,請運行我的代碼並查看問題。

public partial class Form2 : Form
{
    MyBackgroundWorker backgroundWorker1 = null;
    Dictionary<string, string> dct = new Dictionary<string, string>();
    public Form2()
    {
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {

    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        backgroundWorker1 = new MyBackgroundWorker();
        backgroundWorker1.WorkerReportsProgress = true;   
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
        backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
        backgroundWorker1.RunWorkerAsync(txtNumber.Text);

    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        string strID = DateTime.Now.ToString("yyyyMMdd") + DateTime.Now.ToString("hhmmss")+DateTime.Now.Millisecond.ToString();
        MyBackgroundWorker tmpBg = (sender as MyBackgroundWorker);
        tmpBg.Name = "bg_" + strID;

        ProgressBar pb = new ProgressBar();
        pb.Minimum = 0;
        pb.Maximum = 100;
        pb.Name = "pb_" + strID;
        pb.Width = txtNumber.Width;
        this.BeginInvoke((MethodInvoker)delegate
        {
            flowLayoutPanel1.Controls.Add(pb);
        });

        dct.Add(tmpBg.Name, pb.Name);

        int input = int.Parse(e.Argument.ToString());
        for (int i = 1; i <= input; i++)
        {
            Thread.Sleep(2000);
            backgroundWorker1.ReportProgress(i * 10);
            if (backgroundWorker1.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
        }
    }

    // This event handler updates the progress bar. 
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        MyBackgroundWorker tmpBg = (sender as MyBackgroundWorker);
        string strName = tmpBg.Name;

        if (!string.IsNullOrEmpty(strName))
        {
            strName = strName.Substring(3);
            ProgressBar pb = (ProgressBar)this.flowLayoutPanel1.Controls.Find(("pb_" + strName), true)[0];
            pb.Value = e.ProgressPercentage;
        }
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MyBackgroundWorker tmpBg = (sender as MyBackgroundWorker);
        string strName = tmpBg.Name;
        strName = strName.Substring(3);
        ProgressBar pb = (ProgressBar)this.flowLayoutPanel1.Controls.Find(("pb_" + strName), true)[0];
        pb.Value = 100;
        //MessageBox.Show("Done");
    }

}

    public class MyBackgroundWorker : System.ComponentModel.BackgroundWorker
        {
            public MyBackgroundWorker()
            {
            }

            public MyBackgroundWorker(string name)
            {
                Name = name;
            }

            public string Name { get; set; }
        }

更新部分

 private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MyBackgroundWorker tmpBg = (sender as MyBackgroundWorker);
            string strName = tmpBg.Name;
            strName = strName.Substring(3);
            ProgressBar pb = (ProgressBar)this.flowLayoutPanel1.Controls.Find(("pb_" + strName), true)[0];
            //pb.Value = 100;
            //MessageBox.Show("Done");
            flowLayoutPanel1.Controls.Remove(pb);
        }

我想我可以按您的意願進行操作。

  1. 在ProgressChanged中,我以另一種方式獲取進度條。

  2. 在DoWork中,我以進度百分比報告了當前backgroundWorker的進度。

  3. 我刪除Thread.Sleep是因為我認為這是引起問題的原因,因此在DoWork添加了Console.WriteLine來減慢程序速度(否則它比ProgressBar呈現的速度更快)

     public partial class Form2 : Form { MyBackgroundWorker backgroundWorker1 = null; Dictionary<string, string> dct = new Dictionary<string, string>(); public Form2() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void btnStart_Click(object sender, EventArgs e) { backgroundWorker1 = new MyBackgroundWorker(); backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted); backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); backgroundWorker1.RunWorkerAsync(int.Parse(txtNumber.Text)); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string strID = DateTime.Now.ToString("yyyyMMdd") + DateTime.Now.ToString("hhmmss") + DateTime.Now.Millisecond.ToString(); MyBackgroundWorker tmpBg = (sender as MyBackgroundWorker); tmpBg.Name = "bg_" + strID; ProgressBar pb = new ProgressBar(); pb.Minimum = 0; pb.Maximum = 100; pb.Name = "pb_" + strID; pb.Width = txtNumber.Width; this.BeginInvoke((MethodInvoker)delegate { flowLayoutPanel1.Controls.Add(pb); }); dct.Add(tmpBg.Name, pb.Name); int input = (int)e.Argument; for (int i = 1; i <= input; i++) { Console.WriteLine(tmpBg.Name + ": " + (i * 100 / input)); //for testing (this line slows the program down a lot) tmpBg.ReportProgress(i * 100 / input); if (tmpBg.CancellationPending) { e.Cancel = true; return; } } } // This event handler updates the progress bar. private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { MyBackgroundWorker tmpBg = (sender as MyBackgroundWorker); string strName = tmpBg.Name.Substring(3); ProgressBar pb; if (!string.IsNullOrEmpty(strName)) { foreach (Control c in flowLayoutPanel1.Controls) { if (c.Name == ("pb_" + strName)) { pb = (ProgressBar)c; pb.Value = Math.Min(100,e.ProgressPercentage); } } } } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { MyBackgroundWorker tmpBg = (sender as MyBackgroundWorker); string strName = tmpBg.Name; strName = strName.Substring(3); ProgressBar pb = (ProgressBar)this.flowLayoutPanel1.Controls.Find(("pb_" + strName), true)[0]; pb.Value = 100; //MessageBox.Show("Done"); } } public class MyBackgroundWorker : System.ComponentModel.BackgroundWorker { public MyBackgroundWorker() { } public MyBackgroundWorker(string name) { Name = name; } public string Name { get; set; } } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM