我的理解是,Thread.Abort應該在阻塞的線程上引發一個ThreadAbortException,但是在處理TcpListener.AcceptSocket
時似乎不是這種情況。下面是問題的最基本的例證:AcceptSocket不尊重一個Thread.Abort請求
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
爲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");
}
}
在「顯示」,它這種情況下很好地工作。 ThreadAbortException在線程正在執行WaitOne時被捕獲。但是,這種被調用BeginAcceptSocket創建線程仍在運行,並且能夠接受一個插座
最後(我打開使用Telnet端口驗證了這一點),我添加Listener.Stop
爲TheadAbortException
處理程序的一部分,並一試捕捉EndAcceptSocket調用(因爲套接字由Stop來處理)
這真的是啓動和停止偵聽套接字連接的最佳方法嗎?
當你終止線程時clientConnected事件會發生什麼?你爲什麼不處理物體?你對插座一旦接受了怎麼辦? – 2011-04-25 12:26:16
使用'Thread.Abort'幾乎總是一個骯髒的黑客應該避免。讓你的線程優雅地終止...不要從他們下面拉地毯。 – spender 2011-04-25 12:56:14