问题
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