如何杀死一个线程?

问题描述:

我有一个线程在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;  
    } 
} 

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

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

while (!CancellationPending) 
{ 
    // do stuff 
} 

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

您应该在您的Reader功能中加入ManualResetEvent。而不是while(true),while(!mManualReset.WaitOne(0))。然后,在退出程序之前,先执行mManualReset.Set(),这将让线程优雅地退出。

+0

如何使用该自动复位? – 2011-02-12 15:17:23

+0

真的很糟糕的方式来与线程交互太... – 2011-02-12 17:22:58