mikrocontroller.net

Forum: PC-Programmierung Thread beenden


Autor: Threader (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich habe foglenden Codeausschnitt:
public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;  
            button1.Text = "Connect";
            Thread mythread = new Thread(new ThreadStart(listen_tcp));
            mythread.Start();
        }
...
Jetzt möchte ich "mythread" beim Schließen des Hauptformulars beenden, 
allerdings ist "mythread" in der Formclosing Methode gar nicht bekannt. 
Bin nicht so der C# Experte, aber da Form() public ist, sollte ich auf 
mythread aus anderen Methoden zugreifen können oder nicht?
Grüße
Martin

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Trotz public kannst du auf mythread nicht von außen
zugreifen, weil es eine lokale Variable der Methode ist.
Dazu müsstest du sie außerhalb der Methode (in der Klasse z.B.)
ansiedeln.

Einer, der auch keine Ahnung von C# hat...

Autor: Threader (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super, jetzt kann ich drauf zugreifen. Nur wenn ich das Formular 
schließe, muss ich im Visual Studio danach noch explizt auf Debuggen 
beenden gehen. Ohne Thread schließt es richtig, Thread wird mit Abort() 
beendet. Da noch jemand ne Idee?

Autor: Sven H. (dsb_sven)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Wenn dein Thread mit irgendwas beschäftigt ist, kann er die 
ThreadAbortExreption (die von Thread.Abort() ausgelöst wird) nicht 
behandeln.

Eine Möglichkeit wäre den Thread in einen Try-Catch einzubauen und die 
ThreadAbortException aufzufangen:
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Thread t;

        private void button1_Click(object sender, EventArgs e)
        {
            t = new Thread(new ThreadStart(work));
            t.Start();
        }

        void work()
        {
            try
            {
                while (true)
                {
                    // do something
                }
            }
            catch (ThreadAbortException ex)
            {
                // stop doing something
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            t.Abort();
        }
    }

Alternativ kannst du whs auch innerhalb deiner Thread schleife irgendwo 
Application.DoEvents() einbauen. Das habe ich aber nicht getestet und 
finde es auch nicht so schön.

Autor: Sven H. (dsb_sven)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso, und nochwas
CheckForIllegalCrossThreadCalls = false;  

ist nicht schön. Es hat schon seinen Sinn, dass auf illegale 
threadübergreifende Zugriffe geachtet wird. Du solltest dich mal mit dem 
Thema Delegaten auseinandersetzen. (Stichwort "invoke")

Autor: Threader (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sven
habs mal so versucht, klappt allerdings noch nicht ganz:
public void listen_tcp()
         {
            try
            {
                IPAddress ipAddress = IPAddress.Any;
                listener = new TcpListener(ipAddress, 12345);
                listener.Start();
                Console.WriteLine("Server is running");
                Console.WriteLine("Listening on port " + 12345);
                Console.WriteLine("Waiting for connections...");
                label15.Text = "test";
            -->    s = listener.AcceptSocket();
            -->    Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
                //while (s.Connected == true)
                //{

                //    byte[] b = new byte[20];
                //    int k = s.Receive(b);
                //    Console.WriteLine("Received:");
                //    for (int i = 0; i < k; i++)
                //        Console.Write(Convert.ToChar(b[i]));
                //    ASCIIEncoding enc = new ASCIIEncoding();
                //    s.Send(enc.GetBytes("Server responded"));
                //    Console.WriteLine("\nSent Response");
                //    //s.Close();
                //}
            }
            catch (ThreadAbortException ex)
            {
          
                listener.Stop();
                s.Close();
                s = null;
            }

            }
Wenn ich die markierten 2 Zeilen auskommentiere klappt es, anscheinend 
krieg ich das Socket nicht ausser Gefecht gesetzt. Hast du da noch ne 
Idee? Ich weiss dass das alles nicht so ganz sauber ist...

Autor: Sven H. (dsb_sven)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Puh :-)

Was ist denn s? Der (oder heißt es 'das') Socket?

Offensichtlich ist listerner.AcceptSocket() ein blockierender Aufruf. 
Schau mal, ob du nen Timeout angeben kannst, oder es ne asynchrone 
Variante davon gibt.

Autor: eugler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: c# (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Threader schrieb:
> aber da Form() public ist, sollte ich auf
> mythread aus anderen Methoden

Aber mythread ist eine lokale Variable, die nach dem CTOR nicht greifbar 
ist. Nur so als Info ;-).

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.