ThreadAbort无法使用套接字中的readline

时间:2010-03-03 10:56:01

标签: c# sockets

我使用线程打开服务器的套接字并以同步方式从服务器读取数据来实现TCP客户端。 当行String thisLine = aReadStream.ReadLine();阻塞因为没有数据要从套接字中读取而我尝试执行Thread.Abort来杀死该线程(因为它在该ReadLine()上被阻塞)我希望能够抓住ThreadAbortException 我不能。

线程在ReadLine()上仍然被阻止,并且没有被杀死。 在我的线程中使用的代码下面。

你知道为什么和我做错了什么以及如何解锁ReadLine()?

private void readSocket_andTriggerEvents()
{            
    TcpClient aClient = null;         

    try
    {
        aClient = new TcpClient();
        aClient.Connect(_HOST, _PORT);
        Trace.WriteLine("Socket Connected");

        NetworkStream aStream = aClient.GetStream();
        StreamReader aReadStream = new StreamReader(aStream);
        int nTimes = 0;

        while (this.isSocketThreadStarted) 
        {

            String thisLine = aReadStream.ReadLine(); // when no data
            // is available the application hangs here.
            // Thread.Abort doesn't work!
           }
    }                
    catch (ThreadAbortException ex)
    {
        Trace.WriteLine("The Thread was brute-forced killed");
        // I never come here!!
    }
    catch (SocketException ex)
    {
        Helper.ShowErrorMessage(ex);
    }
    finally{
        aClient.Close();
        Trace.WriteLine("socket closed");
     }

}

2 个答案:

答案 0 :(得分:2)

从另一个线程关闭套接字。当ReadLine被阻止时,这应该抛出SocketException。

答案 1 :(得分:0)

不要将StreamReader与网络流一起使用。它无法与无限流一起使用。

至于为什么Thread.Abort不起作用,这非常简单 - Thread.Abort仅在线程处于WaitSleepJoin状态或类似状态时才有效。如果线程正在运行,那么置于托管代码中 - 阻塞套接字调用最有可能在非托管代码中运行(/阻塞),因此Abort在返回之前无法工作。没有办法“杀死”一个线程 - 可以(或多或少)安全地杀死的最小的东西是一个过程。

这就是为什么Thread.Abort如果你之后关闭套接字会神奇地开始工作的原因 - 解除对线程的阻塞并使其返回托管代码,Thread.Abort可以在其中执行其hacky魔法。