Benutzer mit den meisten Antworten
ButtonKlick wird doppelt aufgerufen

Frage
-
Hallo ich habe einen Button, mit welchem ich einen BackgroundWorkeer starten und stoppen will.
Leider wird er aufgerufen, startet nach einem Sleep den Backgroundworker und wird anschließend wieder aufgerufen und stoppt den Backgroundworker wieder. Weis jemand warum und wie man dass verhindern kann?
private void StartStopp_Click(object sender, EventArgs e) { if (btStartStopp.Text == "Start Spam") { if (Wartezeit < 1000) { Wartezeit = 1000; } btStartStopp.Text = "Stopp Spam"; System.Threading.Thread.Sleep(3000); backgroundWorker1.RunWorkerAsync(); } else if (btStartStopp.Text == "Stopp Spam") { btStartStopp.Text = "Start Spam"; backgroundWorker1.CancelAsync(); a = 0; } }
Antworten
-
Hallo B.,
was auffälig ist, ist, dass "... .Sleep(3000);", was den Mainthread blockiert.
Das ist sicher auch so gemeint, dass es nach dem Aufruf von RunWorkerAsync() ausgeführt werden soll.
Aber selbst das wäre schlecht, denn so wird der Main-Thread ja auch 3 Sekunden blockiert.
Du willst die Verzögerung ja aber im DoWork simulieren, sodass der MainThread natürlich nicht blockiert.
Ansonsten können Fehler nur in dem Teil des Codes liegen, den Du uns nicht gepostet hast.
Also mal ein funktionsfähiges Beispiel (mit Deinem Code) :using System; using System.ComponentModel; using System.Threading; using System.Windows.Forms; namespace WinButtonClickDoppelt { public partial class Form1 : Form { private BackgroundWorker backgroundWorker1; private Button btStartStopp; private ProgressBar progressBar1; public Form1() { Initialisiere(); btStartStopp.Click += StartStopp_Click; } private void Initialisiere() { this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); this.btStartStopp = new System.Windows.Forms.Button(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.SuspendLayout(); // // backgroundWorker1 // this.backgroundWorker1.WorkerReportsProgress = true; this.backgroundWorker1.WorkerSupportsCancellation = true; this.backgroundWorker1.DoWork += new DoWorkEventHandler(this.backgroundWorker1_DoWork); this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); // // btStartStopp // this.btStartStopp.Location = new System.Drawing.Point(23, 29); this.btStartStopp.Name = "btStartStopp"; this.btStartStopp.Size = new System.Drawing.Size(75, 23); this.btStartStopp.TabIndex = 0; this.btStartStopp.Text = "Start Spam"; this.btStartStopp.UseVisualStyleBackColor = true; // // progressBar1 // this.progressBar1.Location = new System.Drawing.Point(23, 83); this.progressBar1.Name = "progressBar1"; this.progressBar1.Size = new System.Drawing.Size(199, 23); this.progressBar1.TabIndex = 1; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(284, 262); this.Controls.Add(this.progressBar1); this.Controls.Add(this.btStartStopp); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } int Wartezeit = 4000; int a; private void StartStopp_Click(object sender, EventArgs e) { if (btStartStopp.Text == "Start Spam") { if (Wartezeit < 1000) { Wartezeit = 1000; } btStartStopp.Text = "Stopp Spam"; backgroundWorker1.RunWorkerAsync(); //System.Threading.Thread.Sleep(Wartezeit); } else if (btStartStopp.Text == "Stopp Spam") { btStartStopp.Text = "Start Spam"; backgroundWorker1.CancelAsync(); a = 0; } } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //if (e.Cancelled) MessageBox.Show("Aktion abgebrochen"); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { for (int i = 1; i <= 100; i++) { if (backgroundWorker1.CancellationPending) { MessageBox.Show("In DoWork Beendet"); e.Cancel = true; return; } Thread.Sleep(100); backgroundWorker1.ReportProgress(i); } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; this.Text = e.ProgressPercentage.ToString(); } } }
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Montag, 10. Januar 2011 10:55
-
Ich habe jetzt das Sleep herausgenommen und an den Anfang des Backgroundworkers gelegt, so funktioniert es.
- Als Antwort markiert Robert BreitenhoferModerator Montag, 10. Januar 2011 10:56
Alle Antworten
-
Hallo Benson,
ich kann erst einmal nichts auffälliges entdecken, ausser dass Du da ein Thread.Sleep von 3 Sekunden im UI Thread durchführst.
Was Du prüfen solltest:
a) Klickst du evtl. mehrfach? Denn Du setzt zwar den Text des Buttons, aber der wird ja nicht neu gemalt da der UI Thread 3 Sekunden schläft! Somit könnte es gut sein, dass du nochmal klickst, "weil er den ersten Klick nicht genommen hat".
b) Hast Du evtl. mehrere Events mit deiner Funktion verknüpft? Dann könnte es durchaus sein, dass die Funktion mehrfach aufgerufen wird....
Mit den besten Grüßen,
Konrad
-
ich habe nicht mehrfach geklickt. mir ist aufgefallen, wenn ich nur den aufruf vom backgroundWorker herausnehme funktioniert es. Als ob er nach diesem Aufruf direkt wieder in den Button springen würde.
Habe mir jetzt einfach nen 2. Button gemacht (aus Zeit gründen) aber komisch dass es nicht geht.
-
Was ruft denn der Worker für eine Routine auf? Falls es das sein sollte. Schau zur not einfach mal über den Design code drüber, was für Event Verknüpfungen sich so alles finden. Und speziell auf die DoWork Verknüpfung(en) achten,
Mit den besten Grüßen,
Konrad
-
Hallo B.,
was auffälig ist, ist, dass "... .Sleep(3000);", was den Mainthread blockiert.
Das ist sicher auch so gemeint, dass es nach dem Aufruf von RunWorkerAsync() ausgeführt werden soll.
Aber selbst das wäre schlecht, denn so wird der Main-Thread ja auch 3 Sekunden blockiert.
Du willst die Verzögerung ja aber im DoWork simulieren, sodass der MainThread natürlich nicht blockiert.
Ansonsten können Fehler nur in dem Teil des Codes liegen, den Du uns nicht gepostet hast.
Also mal ein funktionsfähiges Beispiel (mit Deinem Code) :using System; using System.ComponentModel; using System.Threading; using System.Windows.Forms; namespace WinButtonClickDoppelt { public partial class Form1 : Form { private BackgroundWorker backgroundWorker1; private Button btStartStopp; private ProgressBar progressBar1; public Form1() { Initialisiere(); btStartStopp.Click += StartStopp_Click; } private void Initialisiere() { this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); this.btStartStopp = new System.Windows.Forms.Button(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.SuspendLayout(); // // backgroundWorker1 // this.backgroundWorker1.WorkerReportsProgress = true; this.backgroundWorker1.WorkerSupportsCancellation = true; this.backgroundWorker1.DoWork += new DoWorkEventHandler(this.backgroundWorker1_DoWork); this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); // // btStartStopp // this.btStartStopp.Location = new System.Drawing.Point(23, 29); this.btStartStopp.Name = "btStartStopp"; this.btStartStopp.Size = new System.Drawing.Size(75, 23); this.btStartStopp.TabIndex = 0; this.btStartStopp.Text = "Start Spam"; this.btStartStopp.UseVisualStyleBackColor = true; // // progressBar1 // this.progressBar1.Location = new System.Drawing.Point(23, 83); this.progressBar1.Name = "progressBar1"; this.progressBar1.Size = new System.Drawing.Size(199, 23); this.progressBar1.TabIndex = 1; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(284, 262); this.Controls.Add(this.progressBar1); this.Controls.Add(this.btStartStopp); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } int Wartezeit = 4000; int a; private void StartStopp_Click(object sender, EventArgs e) { if (btStartStopp.Text == "Start Spam") { if (Wartezeit < 1000) { Wartezeit = 1000; } btStartStopp.Text = "Stopp Spam"; backgroundWorker1.RunWorkerAsync(); //System.Threading.Thread.Sleep(Wartezeit); } else if (btStartStopp.Text == "Stopp Spam") { btStartStopp.Text = "Start Spam"; backgroundWorker1.CancelAsync(); a = 0; } } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //if (e.Cancelled) MessageBox.Show("Aktion abgebrochen"); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { for (int i = 1; i <= 100; i++) { if (backgroundWorker1.CancellationPending) { MessageBox.Show("In DoWork Beendet"); e.Cancel = true; return; } Thread.Sleep(100); backgroundWorker1.ReportProgress(i); } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; this.Text = e.ProgressPercentage.ToString(); } } }
ciao Frank- Als Antwort markiert Robert BreitenhoferModerator Montag, 10. Januar 2011 10:55
-
Ich habe jetzt das Sleep herausgenommen und an den Anfang des Backgroundworkers gelegt, so funktioniert es.
- Als Antwort markiert Robert BreitenhoferModerator Montag, 10. Januar 2011 10:56