2010-03-03 58 views
0

我使用一个线程打开套接字到服务器并以同步的方式从中读取数据,从而实现了一个TCP客户机。 当行String thisLine = aReadStream.ReadLine();块,因为没有数据从套接字阅读,我尝试执行Thread.Abort杀死线程(因为它被阻止上的ReadLine()),我希望能够赶上ThreadAbortException我不能。ThreadAbort不能与插槽中的readline一起使用

该线程在该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

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

+0

感谢您的帮助!还有一件事情,如果你还在身边:你知道为什么ThreadAbortException不会像我期望的那样抛出吗? – 2010-03-03 11:31:35

+0

@Abruzzo Forte e外邦人:对不起,不知道。但是不建议使用Thread.Abort。 – dtb 2010-03-03 11:57:40

+0

是的,我知道,但在这种情况下,因为我没有使用异步套接字,所以它是我唯一能做的事情。 顺便说一句,我偶然发现,如果我先打电话.Abort()然后_socket.Close()ThradAbortExcepion可以赶上。 感谢您的大力帮助! Ciao – 2010-03-03 12:03:38

0

请勿将StreamReader与网络流一起使用。它对于无限流不适用。

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

这就是为什么Thread.Abort奇迹般地开始工作,如果你之后关闭套接字 - 解除阻塞线程,并使其返回到托管代码,其中Thread.Abort可以做它的哈克魔法。

相关问题