开发者

ThreadAbort not working with readline from a socket

开发者 https://www.devze.com 2022-12-21 23:22 出处:网络
I implemented a TCP Client using a thread opening a socket to a server and reading data from it in synchronous way.

I implemented a TCP Client using a thread opening a socket to a server and reading data from it in synchronous way. When the line String thisLine = aReadStream.ReadLine(); blocks because there is no data to read from the socket and I try to perform a Thread.Abort to kill the thread ( since it is blocked on that ReadLine() ) I expect to be able to catch a ThreadAbortException BUT I can't.

The thread remains blocked on that ReadLine() and is not killed. Below the code I am using in my Thread.

Do you know why and what I am doing wrong and what to do to unblock that 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!!
开发者_JS百科    }
    catch (SocketException ex)
    {
        Helper.ShowErrorMessage(ex);
    }
    finally{
        aClient.Close();
        Trace.WriteLine("socket closed");
     }

}


Close the socket from a different thread. This should throw a SocketException when ReadLine is blocked.


Don't use StreamReader with network streams. It just doesn't work well with infinite streams.

As for why Thread.Abort doesn't work, that's really simple - Thread.Abort only works when the thread is either in WaitSleepJoin state or similar. If the thread is running, it has to be in managed code - a blocking socket call is most likely running(/blocking) in unmanaged code, thus the Abort cannot work until it returns. There's no way to "kill" a thread - the smallest thing that can be (more or less) safely killed is a process.

That's of course why Thread.Abort magically starts working if you close the socket afterwards - that unblocks the thread and causes it to go back to managed code, where Thread.Abort can do its hacky magic.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号