www.mikrocontroller.net

Forum: PC-Programmierung C# Endlosschleifen mit Button unterbrechen


Autor: Rene Pratsch (rene1989)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe 2 Buttons
Mit dem 1. will ich die Endlosschleife starten und mit dem anderen 
wieder beenden.
Mein Problem ist das während der Endlosschleife die Buttons nicht mehr 
betätigen kann weil er in der Schleife "hängen" bleibt.
//Start
private void start_Click(object sender, EventArgs e)
{
...
  while() Endlosschleife
}

//Stop
private void stop_Click(object sender, EventArgs e)
{
  ...Endlosschleife unterbrechen
}

danke schon im Voraus für eure Hilfe

mfg Rene

Autor: Mars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast ja auch nur einen Thread. Wenn dieser in der Schleife hängt, 
kannst du logischerweise den zweiten Button nicht mehr drücken.
=> Endlosschleife in einen eigenen Thread auslagern. Die 
BackgroundWorker Klasse nimmt dir einiges an Arbeit ab und die Beispiel 
in der MSDN sind auch sehr gut.

Lg

Autor: Rene Pratsch (rene1989)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm mit C# sharp hab ich mich noch nicht so gut befasst

Wie kann man einen 2.Tread machen?

danke mfg

Autor: Mars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann wird es aber Zeit!

Nimm die BackgroundWorker Klasse, diese nimmt dir bereits die 
Threadsynchronisierung für GUI Zugriffe ab.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Application.DoEvents() innerhalb der Schleife gehts auch ohne 
Multithreading.

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian wrote:
> Mit Application.DoEvents() innerhalb der Schleife gehts auch ohne
> Multithreading.

Ja, und in stop_Click() Flag setzen und in der Endlosschleife abfragen.

Flag initialisieren nicht vergessen!

Autor: Chris ... (dechavue)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ich möchte noch anmerken, dass die Methode mit Application.DoEvents() 
eher die Quick and VERY DIRTY - Methode ist.

Besser ist es, das Ganze mit Threads zu machen, was ja dank 
Backgroundworker überhaupt keine Hexerei ist.

Anbei ein Kleines Beispiel, wie das Ganze mit dem BW funktioniert (inkl. 
Parameterübergabe, Ergebnisrückgabe und Fortschrittsmeldung 
zwischendurch)
        private BackgroundWorker m_BackgroundWorker = new BackgroundWorker();

        public Form1() {
            InitializeComponent();

            m_BackgroundWorker.DoWork += new DoWorkEventHandler(m_BackgroundWorker_DoWork);
            m_BackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(m_BackgroundWorker_ProgressChanged);
            m_BackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_BackgroundWorker_RunWorkerCompleted);
            m_BackgroundWorker.WorkerReportsProgress = true;
        }

        private void m_BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
            // GUI - Thread

            //e.Cancelled ... Indicates if the Operation was cancelled
            //e.Error     ... An Exception which was thrown inside the Async Operation
            //e.Result    ... A Result Object
        }

        private void m_BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
            // GUI - Thread
            
            //z.B.:
            //m_Progressbar.Value = e.ProgressPercentage
            //Do Something with e.UserState
        }

        private void m_BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
            //Worker - Thread
            
            //Do Something with e.Argument
            int i = 0;
            do {
                m_BackgroundWorker.ReportProgress(i++ % 100/*, Optional: any Object*/);
            } while (!e.Cancel);
            //e.Result = Any result Object
        }

        private void button1_Click(object sender, EventArgs e) {
            m_BackgroundWorker.RunWorkerAsync(/*Optional: Any Object*/);
        }

        private void button2_Click(object sender, EventArgs e) {
            m_BackgroundWorker.CancelAsync();
        }

greets

PS: Ich appeliere nochmal an dich BITTE nimm nicht 
Application.DoEvents(), du handelst dir damit früher oder später nur 
Probleme ein.

Autor: Rene Pratsch (rene1989)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielen dank für deine Hilfe
ich habe jetzt eine weile experimentiert aber verstehe noch immer nicht 
wie der Backgroundworker genau funktioniert.

wie würde ich eine Endlosschleife machen, die in einem Label immer die 
Zahl um 1 erhöht. Mit einem Button wird die Schleife gestartet und mit 
einem anderen wieder abgebrochen.

Autor: Crimson (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

verwende für so etwas doch einfach einen Timer mit einem Click auf den 
Button 1 wird der Timer gestartet und mit einem Click auf den Button 2 
wieder angehalten. In dem Timer kann man dan auch noch den zeitlichen 
Abstand einstellen.
Z.B.:
public partial class Form1 : Form
    {
        public Timer timer1;
        public long laufvar;
        public Form1()
        {
            InitializeComponent();
            
            timer1 = new Timer();
            timer1.Interval = 1000; // in Millisekunden
            timer1.Tick +=new EventHandler(timer1_Tick);
            laufvar = new long();
            laufvar = 0;
        }

        void  timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = laufvar.ToString();
            laufvar++;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Start();
        }

        

        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Stop();
        }

        
    }

Das einzige was da noch fehlt sind zwei Buttons sowie ein label auf dem 
Form1 und du hast eine Sekunden Stopuhr.
Aber für so etwas würde ich nicht mit Threads anfangen.

Autor: Marco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo..

Jetzt habe ich noch mal eine ergänzende Frage zum BW.

Ich muss hin und wieder eine mathematische Operation ausführen, die ich 
in einem separaten Thread laufen lasse. Dieser Thread arbeitet ständig 
und wird nur durch ein Thread.Sleep für einige Zeit zum stoppen 
gebracht.

Thread worker = new Thread(Work);
worker.Start();
private void Work()     
{
 while (true)
 {
    try 
    {
      //...Berechne...
      Thread.Sleep(1000);
    }   
    catch(Exception) {}
  }
}

Natürlich ist diese Art der Programmierung "very very dirty", allerdings 
kann ich einen BW, denn ich einmalig initialisiert habe, auch mehrfach 
starten und stoppen?

Autor: Raphael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bool beende;
Thread t;
private void button1_Click()
{
   beende = false;
   t = New Thread(new ThreadStart(run));
   t.Start();
}

void run()
{
  while(!beende)
  { /*mache irgendwas*/ }
}

private void  button2_click()
{
    beende = true;
}
So würde es mal aussehen, wenn man nicht den BW nehmen will.

Autor: Klugscheisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann ist das doch aber keine ENDLOSschleife mehr wenn die unterbrochen 
wird!

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es dürfte auch nicht allzuviele echte Endlosschleifen geben. Irgendwie 
werden sie doch alle früher oder später unterbrochen.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gilt das mit VOLATILE eigentlich für C# nicht mehr?

Autor: Andreas F. (andilein)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann mir jemand sagen wie ich zu meinem label komme?
also ich sollte den "label1.Text" ändern!

..es geht um diesen beitrag hier:


Autor: Crimson (Gast)
Datum: 24.02.2009 17:04

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas F. schrieb:
> kann mir jemand sagen wie ich zu meinem label komme?
> also ich sollte den "label1.Text" ändern!

Zieh einfach ein Label-Control aus deinem Controlvorrat auf die Form.

(PS: Sag niemandem, dass du C# programmierst)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.