Thread.Abort()方法无法终止线程

z_songlin 2014-06-02 11:16:27
做的是一个服务器-客户端通信的小程序。
服务器端中接受连接和接收消息分别在两个线程中完成。
在响应窗口的FormClosing事件中调用 Abort()方法终止这两个进程,但是程序还是没有退出。

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

namespace Server
{
public partial class Server : Form
{
private Socket serverSocket;
// private Socket clientSocket;
private Thread receiveThread;
private Thread connectThread;

public Server()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}

private void buttonStart_Click(object sender, EventArgs e)
{
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint iep = new IPEndPoint(ip, 5555);
this.serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(iep);
serverSocket.Listen(500);

this.connectThread = new Thread(new ThreadStart(this.AcceptConnect));
this.connectThread.Start();
}

private void AcceptConnect()
{
this.serverSocket = this.serverSocket.Accept();
this.serverSocket.Send(Encoding.UTF8.GetBytes("服务器连接成功!\r\n"));
this.receiveThread = new Thread(new ThreadStart(ReceiveMessage));
this.receiveThread.Start();

//this.connectThread.Abort();
}

private void ReceiveMessage()
{
byte[] buf;
try
{
while (true)
{
buf = new byte[512];
this.serverSocket.Receive(buf);
string receiveString = Encoding.UTF8.GetString(buf);
this.textBoxReceive.Text += "客户端说:" + receiveString + "\r\n";

}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

private void Server_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.receiveThread != null)
this.receiveThread.Abort();

if (this.connectThread != null)
{
//connectThread.Join();
this.connectThread.Abort();
}
}

private void buttonSend_Click(object sender, EventArgs e)
{
byte[] buf = Encoding.UTF8.GetBytes(this.textBoxSend.Text);
this.serverSocket.Send(buf);
}
}
}
...全文
2567 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
火星大能猫 2016-11-17
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
最好使用这种方法 .......... 应该尽量避免使用这种方法 至少要看懂这里的文字!
实在看不下去了 人家问的是无法终止线程 你回答的是啥? 什么最好使用 避免使用 解决不了任何问题! .NET的机制是无法强制结束线程的 abort也不例外.
stherix 2016-10-11
  • 打赏
  • 举报
回复
引用 15 楼 u012948520 的回复:
[quote=引用 1 楼 caozhy 的回复:] 不管你写程序,也不管你做什么,都不要调用Abort()这个方法。
有些线程睡眠时间很长的,比如 while (flag) { // do something Thread.Sleep(1000 * 60 * 60); } 这种不用abort,怎么结束啊[/quote] Abort在某些情况下很有用 但你这种情况最好还是写成 ExitEvent.Wait(1000 * 60 * 60); 需要中止的时候ExitEvent.Set();
白衣如花 2016-10-11
  • 打赏
  • 举报
回复
引用 1 楼 caozhy 的回复:
不管你写程序,也不管你做什么,都不要调用Abort()这个方法。
有些线程睡眠时间很长的,比如 while (flag) { // do something Thread.Sleep(1000 * 60 * 60); } 这种不用abort,怎么结束啊
stherix 2016-10-11
  • 打赏
  • 举报
回复
catch (Exception ex) { MessageBox.Show(ex.Message); } 这里就不要 MessageBox.Show了 其他地方逻辑有问题啊 只支持单连接 虽然不影响你这个问题
裸奔的蜗牛 2016-10-10
  • 打赏
  • 举报
回复
引用 2 楼 trfftrff 的回复:
不建议使用Abort()。 建议添加一个私有变量bool _isContinue;当要结束或者退出时设置_isContinue=false,线程就会跳出死循环,让线程自行终止。以下是修改你的代码:

while (_isContinue)
{
   buf = new byte[512];
    this.serverSocket.Receive(buf);
    string receiveString = Encoding.UTF8.GetString(buf);
    //这里写得有问题,安全机制不允许这样跨线程调用主线程控件。自行度娘修改
     this.textBoxReceive.Text += "客户端说:" + receiveString + "\r\n";
}
this.serverSocket.Receive(buf);这句不就直接阻塞了吗? _isContinue的判断没用吧,
exception92 2014-06-03
  • 打赏
  • 举报
回复
卧槽,这么一说,我以前写的程序都要废了。
z_songlin 2014-06-03
  • 打赏
  • 举报
回复
引用 8 楼 yupeigu 的回复:
若要终止线程的运行,可以使用下面的方法: ·线程函数返回(最好使用这种方法)。 · 通过调用E x i t T h r e a d函数,线程将自行撤消(最好不要使用这种方法)。 · 同一个进程或另一个进程中的线程调用Te r m i n a t e T h r e a d函数(应该尽量避免使用这种方法)。 · 包含线程的进程终止运行(应该尽量避免使用这种方法)。
表示没看懂
threenewbee 2014-06-03
  • 打赏
  • 举报
回复
引用 10 楼 duanzi_peng 的回复:
卧槽,这么一说,我以前写的程序都要废了。
是的,很多人用电脑都把它当作家电,直接拔下插头或者按下接线板的开关就算关机了。也确实,在MSDOS下,似乎文明一点的做法就是退到DOS命令符(天知道有没有驻留程序还在运行),就直接关机。
z_songlin 2014-06-02
  • 打赏
  • 举报
回复
引用 2 楼 trfftrff 的回复:
不建议使用Abort()。 建议添加一个私有变量bool _isContinue;当要结束或者退出时设置_isContinue=false,线程就会跳出死循环,让线程自行终止。以下是修改你的代码:

while (_isContinue)
{
   buf = new byte[512];
    this.serverSocket.Receive(buf);
    string receiveString = Encoding.UTF8.GetString(buf);
    //这里写得有问题,安全机制不允许这样跨线程调用主线程控件。自行度娘修改
     this.textBoxReceive.Text += "客户端说:" + receiveString + "\r\n";
}
线程怎么会出了循环就自动结束呢?
z_songlin 2014-06-02
  • 打赏
  • 举报
回复
引用 1 楼 caozhy 的回复:
不管你写程序,也不管你做什么,都不要调用Abort()这个方法。
为什么呢?
努力的阿牛 2014-06-02
  • 打赏
  • 举报
回复
不建议使用Abort()。 建议添加一个私有变量bool _isContinue;当要结束或者退出时设置_isContinue=false,线程就会跳出死循环,让线程自行终止。以下是修改你的代码:

while (_isContinue)
{
   buf = new byte[512];
    this.serverSocket.Receive(buf);
    string receiveString = Encoding.UTF8.GetString(buf);
    //这里写得有问题,安全机制不允许这样跨线程调用主线程控件。自行度娘修改
     this.textBoxReceive.Text += "客户端说:" + receiveString + "\r\n";
}
threenewbee 2014-06-02
  • 打赏
  • 举报
回复
不管你写程序,也不管你做什么,都不要调用Abort()这个方法。
  • 打赏
  • 举报
回复
最好使用这种方法 .......... 应该尽量避免使用这种方法 至少要看懂这里的文字!
LongRui888 2014-06-02
  • 打赏
  • 举报
回复
若要终止线程的运行,可以使用下面的方法: ·线程函数返回(最好使用这种方法)。 · 通过调用E x i t T h r e a d函数,线程将自行撤消(最好不要使用这种方法)。 · 同一个进程或另一个进程中的线程调用Te r m i n a t e T h r e a d函数(应该尽量避免使用这种方法)。 · 包含线程的进程终止运行(应该尽量避免使用这种方法)。
LongRui888 2014-06-02
  • 打赏
  • 举报
回复
今天刚学了一点多线程,abort是用来终止线程的。 一般来说应该是能用的,之所以在你的程序中没起作用,可能是因为你的线程处于不正常的状态了。 以前在学过windows api中,有TerminateThread好像就是可以终止线程的,但是也说了,状态会处于不确定
努力的阿牛 2014-06-02
  • 打赏
  • 举报
回复
引用 4 楼 qq6680040 的回复:
[quote=引用 2 楼 trfftrff 的回复:] 不建议使用Abort()。 建议添加一个私有变量bool _isContinue;当要结束或者退出时设置_isContinue=false,线程就会跳出死循环,让线程自行终止。以下是修改你的代码:

while (_isContinue)
{
   buf = new byte[512];
    this.serverSocket.Receive(buf);
    string receiveString = Encoding.UTF8.GetString(buf);
    //这里写得有问题,安全机制不允许这样跨线程调用主线程控件。自行度娘修改
     this.textBoxReceive.Text += "客户端说:" + receiveString + "\r\n";
}
线程怎么会出了循环就自动结束呢?[/quote] 一个线程执行完函数后不就自动释放了嘛。
threenewbee 2014-06-02
  • 打赏
  • 举报
回复 1
这还要问为什么么?调用Abort相当于你直接通过拔插头来关闭电脑。

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧