n clicks on a button gives n outputs. Required is only one output resulting from one click

一笑奈何 提交于 2019-12-11 10:24:55

问题


ok.. so i have no idea why this is happening.I saw a similar problem in Java i guess.. but i don't understand any of that stuff. I am working with C# where I have a listview which is updated with remote servers update status on clicking of a button. i have got the code working for this. but when i click on the same button again, the output is displayed twice. If i click on it one more time the output is displayed thrice and so on!! for example: on first click:

xxx     login to server failed
yyy     login to server failed

on second click:

xxx     login to server failed
xxx     login to server failed
yyy     login to server failed
yyy     login to server failed

I am using a backgroundworker, and a parallel foreach loop in it.I have put in all the involved functions here so that there's all the information there.. sorry if that's too much! Here's my code:

    private void button1_Click(object sender, EventArgs e)                        //get update button
    {
        GlobalVariables._count = 0;
        Status.statusProgress obj1 = new Status.statusProgress();
        if (getupdate_button.Text == "Stop")
        {
            backgroundWorker1.CancelAsync();
            getupdate_button.Enabled = false;
        }
        else
        {
            getupdate_button.Text = "Stop";
            listView1.Items.Clear();
            //do stuff
            backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
        }
        if (backgroundWorker1.IsBusy)
        {
            if (backgroundWorker1.CancellationPending != true)
            {
                MessageBox.Show("Please wait till the pervious operation is completed!");
            }
            else 
            {
                Complete_label.Text = "Cancelling...";
                Complete_label.Visible = true;
            }
        }
        else
        {
            backgroundWorker1.RunWorkerAsync(obj1);                                //calling background worker
        }
    }

DO WORK:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)                         //the boss-- the background worker
    {
        System.ComponentModel.BackgroundWorker worker;
        worker = (System.ComponentModel.BackgroundWorker)sender;
        Status obj1 = new Status();
        Status.statusProgress obj = new Status.statusProgress();

        if ((backgroundWorker1.CancellationPending == true))
        {
            e.Cancel = true;
        }
        else
        {
            obj1.Calculation(worker, e);
        }
        e.Result = obj;
    }

CALCULATION METHOD:

    public void Calculation(System.ComponentModel.BackgroundWorker worker, System.ComponentModel.DoWorkEventArgs e)
    {
        Status.statusProgress obj = (Status.statusProgress)e.Argument;
        //stuff

            var file = File.ReadAllLines(obj.SourceFile);

            List<string> namelist = null;
            namelist = new List<string>(file);
            Parallel.ForEach(namelist, /*new ParallelOptions { MaxDegreeOfParallelism = 4 }, */line =>
            //foreach (string line in namelist)
            {
                var progress = new statusProgress();
                progress.TotalSysCount = obj.TotalSysCount;
                Status.statusProgress result = new Status.statusProgress();
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    worker.ReportProgress(result.SysCount, result);
                }
                else
                {
                    //this.SystemName = line;//file.ReadLine();                        
                    progress.SystemName = line;
                    //result = progress;
                    result = OneSystem(line);
                    //work with result
        }
                count1 = Interlocked.Increment(ref count);
                //stuff
                worker.ReportProgress(count1, progress);
                Thread.Sleep(200);

             });

        }
    }

REPORT PROGRESS METHOD:

     private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
    try
                {
                    var newItem = listView1.Items.Add("");
                    newItem.SubItems.Add(result.SystemName);
                    newItem.SubItems.Add(result.StatusString);
                    newItem.SubItems.Add(result.AvailableUpdatesCount.ToString());
                }
                catch (Exception ex)
                {}

            update_text(result);
            progressBar1.Maximum = 100;
            int perc = (int)((result.SysCount * 100) / result.TotalSysCount);
            progressBar1.Value = perc;
            Complete_label.Text = perc.ToString()+"%";
            if (progressBar1.Value == 100)
            {
                Complete_label.Text = "Complete!";
                getupdate_button.Enabled = false;
            }
    }

回答1:


I guess the issue is here:

backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;

If whenever you do the whole click you add a ProgressChanged event handler, after each click you'll be increasing the number of times that the event is being handled.

At the end of the day, you should add event handlers in some application's initialization code or in your class constructor instead of doing so in the click event handler. That is, you'll be sure that you're adding backgroundWorker1_ProgressChanged event handler once per application life-cycle.



来源:https://stackoverflow.com/questions/30475298/n-clicks-on-a-button-gives-n-outputs-required-is-only-one-output-resulting-from

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!