【发布时间】:2011-04-25 12:21:38
【问题描述】:
我的理解是 Thread.Abort 应该在阻塞的线程上引发 ThreadAbortException,但是在处理 TcpListener.AcceptSocket 时似乎并非如此。这是该问题的最基本说明:
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(Listen);
thread.Start();
Thread.Sleep(1000); // give it a second to get going
Console.WriteLine("Aborting listener thread");
thread.Abort();
thread.Join();
Console.WriteLine("Listener thread finished press <enter> to end app.");
Console.ReadLine();
}
static void Listen()
{
try
{
Console.WriteLine("Starting to listen");
TcpListener listener = new TcpListener(IPAddress.Any, 4070);
listener.Start();
Socket socket = listener.AcceptSocket();
Console.WriteLine("Connected!");
return;
}
catch (ThreadAbortException exception)
{
Console.WriteLine("Abort requested");
}
}
}
thread.Abort() 调用应该停止AcceptSocket 并执行ThreadAbortException 处理程序。但是这不会发生。
将我的 AcceptSocket 的 Listen 包装器换成 ListenAsync,它调用 BeginAcceptSocket:
static void ListenAsync()
{
try
{
ManualResetEvent clientConnected = new ManualResetEvent(false);
Console.WriteLine("Starting to listen");
TcpListener listener = new TcpListener(IPAddress.Any, 4070);
listener.Start();
clientConnected.Reset();
var iasyncResult = listener.BeginAcceptSocket((ar) =>
{
Socket socket = listener.EndAcceptSocket(ar);
Console.WriteLine("Connected!");
clientConnected.Set();
}, null);
clientConnected.WaitOne();
return;
}
catch (ThreadAbortException exception)
{
Console.WriteLine("Abort requested");
}
}
在这种情况下,它“似乎”可以正常工作。线程执行 WaitOne 时捕获 ThreadAbortException。然而,通过调用 BeginAcceptSocket 创建的线程仍在运行并且能够接受套接字(我通过使用 Telnet 打开该端口来验证这一点)
最后,我添加了 Listener.Stop 作为 TheadAbortException 处理程序的一部分,并在 EndAcceptSocket 调用周围进行了尝试捕获(因为套接字由 Stop 处理)
这真的是启动和停止侦听套接字连接过程的最佳方法吗?
【问题讨论】:
-
当你杀死线程时,clientConnected 事件会发生什么?你为什么不处理物品?一旦被接受,你会如何处理套接字?
-
使用
Thread.Abort几乎总是一种肮脏的黑客行为,应该避免。让你的线程优雅地终止......不要从它们下面拉地毯。
标签: c# multithreading sockets