i need to terminate a background thread in winform, however, i dont know how. i know that using Thread.Abort, only creates problems..please help

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        StreamReader sr;
        StreamWriter sw;
        TcpClient connection;
        string name;
        private void Form1_Load(object sender, EventArgs e)
        {
            connection = new TcpClient("127.0.0.1", 5000);
            sr = new StreamReader(connection.GetStream());
            sw = new StreamWriter(connection.GetStream());
            ChatterScreen.Text = "Welcome, please enter your name";
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            //Thread t2 = new Thread(Reader);
            //t2.IsBackground = true;
            //t2.Start(connection);
            ThreadPool.QueueUserWorkItem(Reader,connection);// i am trying to kill this thread
            name = InputLine.Text;
        }

        string textinput;
        private void button2_Click(object sender, EventArgs e)
        {
            textinput = InputLine.Text;
            sw.WriteLine(name+":"+textinput);
            sw.Flush();
        }

        string msg;
        string allMessages;
        public void Reader(object o)
        {

            TcpClient con = o as TcpClient;
            if (con == null)
                return;
            while (true)
            {

                msg = sr.ReadLine() + Environment.NewLine;
                allMessages += msg;
                Invoke(new Action(Output));
                Invoke(new Action(AddNameList));
            }
        }

        public void Output()
        {
            ChatterScreen.Text = allMessages;
        
        }

        public string checkForName(string input)
        {
            string name = "";
            for (int i = 0; i < input.Length; i++)
            {
                if (input[i] == ':')
                {
                    name = input.Substring(0, i);
                }
            }
            return name;
        }


        List<string> names = new List<string>();
        public void AddNameList()
        {
            if (!names.Contains(checkForName(msg)))
            {
                names.Add(checkForName(msg));
            }
            comboBox1_DataBind();
            listBox2_DataBind();
        }



        private void listBox2_DataBind()
        {
            Chatters.DataSource = null;
            Chatters.DataSource = names;
        }
        private void comboBox1_DataBind()
        {
            comboBox1.Items.Clear();
            foreach (string item in names)
            {
                comboBox1.Items.Add(item);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sw.WriteLine(comboBox1.Text+"@2@3"+name);
            sw.Flush();
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void richTextBox2_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

I think the easiest way to stop your thread would be to break out of your while loop in the Reader method on a certain condition.

while (true)
{
  if (shouldIStop())
     break;
  msg = sr.ReadLine() + Environment.NewLine;
  allMessages += msg;
  Invoke(new Action(Output));
  Invoke(new Action(AddNameList));
}

private bool shouldIStop()
{
  // write some code here for the conditions when you want to stop your thread
}

EDIT: Also, once you break out of the while-loop you should probably do a graceful disconnect from the TCP connection.

Edited 5 Years Ago by darkagn: n/a

well. the server shoots an exception when the connection stops, so i have no problem for that.

The problem is that i dont understand how that background thread works, therefore , i dont know how to tell it to stop..

if i shut down the server first, then the forms throw an exception

i mean, ObjectdisposedException happens at line where: Invoke(new Action(Output));

that exception is thrown when i close the server (while the client is connected).. i mean i could put try and catch around the loop. but what will i put inside the catch?

You should create a class to hold the methods needed to do the background work. In this class you would have a method "DoWork" which is where all the work would be done. It would also include a method "Abort" which would set a boolean to let the thread know if it should continue working on nor. Check this boolean in "DoWork" and when it is set to the abort status, stop working (exit the method while cleaning up resources).

Abort doesnt work. it creates problems, i used it already

You misunderstand completely. Here is an example:

class MyThreadWorkerClass {
    private Boolean keepWorking = true;

    public void DoWork() {
        // set up code here
        while (keepWorking) {
            // do something that is short and fast and repetitive
            // if your code doesn't perform repetitive tasks then
            // you'll need to put checks periodically
        }
        // clean up code goes here
    }

    public void AbortWork() {
        keepWorking = false;
    }
}

With this type of design the thread ends itself, so you can include any type of clean up code you need.

Comments
Thanks for the code

ooooh,, i get it, i think i should wrap the loop in try and catch. in the catch i will call the method, AbortWork. am i right?

This question has already been answered. Start a new discussion instead.