如何杀死一个线程?
问题描述:
我有一个线程在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(),这将让线程优雅地退出。
如何使用该自动复位? – 2011-02-12 15:17:23
真的很糟糕的方式来与线程交互太... – 2011-02-12 17:22:58