ThreadAbort not working with readline from a socket
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.
精彩评论