如何杀死一个线程?

时间:2011-02-12 13:28:48

标签: c# winforms multithreading tcp

我在Winform中有一个帖子。退出应用程序或关闭服务器控制台应用程序后,该线程继续工作。这是代码:

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);//How do i 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)); // An exception is thrown here constantly. sometimes it is thrown and sometimes if i quite the server application , the winform application freezes.
            Invoke(new Action(AddNameList));
        }
    }

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

2 个答案:

答案 0 :(得分:1)

没有做任何工作就没有安全的方法来杀死一个线程:你永远不应该在一个线程上调用Abort;你需要做的是在线程中检测到在完成正常执行之前需要终止它然后你需要告诉它如何执行这个终止。

在C#中,最简单的方法是使用BackgroundWorker,它本质上是一个在后台线程中执行代码的对象;它类似于调用invoke,除了你有更多的控制线程的执行。通过调用RunWorkerAsync()启动worker,并通过调用RunWorkerAsync()指示它取消。调用RunWorkerAsync()后,后台工作程序的CancellationPending属性设置为true;你在代码中注意这个变化(即在你的while循环中),当它为真时你终止(即退出你的while循环)

while (!CancellationPending )
{
  // do stuff
}

我个人通过BackgroundWorkers做所有线程,因为它们易于理解,并提供了在后台和主线程之间进行通信的简便方法

答案 1 :(得分:-1)

您应该在阅读器功能中添加ManualResetEvent。而不是while(true),而是(!mManualReset.WaitOne(0))。然后在退出程序之前执行mManualReset.Set()这将让线程正常退出。