Forum: PC-Programmierung Thread beenden


von Threader (Gast)


Lesenswert?

Hallo zusammen,
ich habe foglenden Codeausschnitt:
1
public Form1()
2
        {
3
            InitializeComponent();
4
            CheckForIllegalCrossThreadCalls = false;  
5
            button1.Text = "Connect";
6
            Thread mythread = new Thread(new ThreadStart(listen_tcp));
7
            mythread.Start();
8
        }
9
...
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

von Klaus W. (mfgkw)


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...

von Threader (Gast)


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?

von Sven H. (dsb_sven)


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:
1
    public partial class Form1 : Form
2
    {
3
        public Form1()
4
        {
5
            InitializeComponent();
6
        }
7
8
        Thread t;
9
10
        private void button1_Click(object sender, EventArgs e)
11
        {
12
            t = new Thread(new ThreadStart(work));
13
            t.Start();
14
        }
15
16
        void work()
17
        {
18
            try
19
            {
20
                while (true)
21
                {
22
                    // do something
23
                }
24
            }
25
            catch (ThreadAbortException ex)
26
            {
27
                // stop doing something
28
            }
29
        }
30
31
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
32
        {
33
            t.Abort();
34
        }
35
    }

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.

von Sven H. (dsb_sven)


Lesenswert?

Achso, und nochwas
1
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")

von Threader (Gast)


Lesenswert?

Hallo Sven
habs mal so versucht, klappt allerdings noch nicht ganz:
1
public void listen_tcp()
2
         {
3
            try
4
            {
5
                IPAddress ipAddress = IPAddress.Any;
6
                listener = new TcpListener(ipAddress, 12345);
7
                listener.Start();
8
                Console.WriteLine("Server is running");
9
                Console.WriteLine("Listening on port " + 12345);
10
                Console.WriteLine("Waiting for connections...");
11
                label15.Text = "test";
12
            -->    s = listener.AcceptSocket();
13
            -->    Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
14
                //while (s.Connected == true)
15
                //{
16
17
                //    byte[] b = new byte[20];
18
                //    int k = s.Receive(b);
19
                //    Console.WriteLine("Received:");
20
                //    for (int i = 0; i < k; i++)
21
                //        Console.Write(Convert.ToChar(b[i]));
22
                //    ASCIIEncoding enc = new ASCIIEncoding();
23
                //    s.Send(enc.GetBytes("Server responded"));
24
                //    Console.WriteLine("\nSent Response");
25
                //    //s.Close();
26
                //}
27
            }
28
            catch (ThreadAbortException ex)
29
            {
30
          
31
                listener.Stop();
32
                s.Close();
33
                s = null;
34
            }
35
36
            }
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...

von Sven H. (dsb_sven)


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.

von eugler (Gast)


Lesenswert?


von c# (Gast)


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 ;-).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.