none
ButtonKlick wird doppelt aufgerufen RRS feed

  • 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;
          }
        }
    Donnerstag, 6. Januar 2011 01:15

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
    Donnerstag, 6. Januar 2011 07:09
  • Ich habe jetzt das Sleep herausgenommen und an den Anfang des Backgroundworkers gelegt, so funktioniert es.
    Donnerstag, 6. Januar 2011 12:49

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

    Donnerstag, 6. Januar 2011 02:28
  • 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.

    Donnerstag, 6. Januar 2011 02:42
  • 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

     

    Donnerstag, 6. Januar 2011 03:01
  • 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
    Donnerstag, 6. Januar 2011 07:09
  • Ich habe jetzt das Sleep herausgenommen und an den Anfang des Backgroundworkers gelegt, so funktioniert es.
    Donnerstag, 6. Januar 2011 12:49