ThreadAbort не работает с readline из сокета - PullRequest
0 голосов
/ 03 марта 2010

Я реализовал TCP-клиент, используя поток, открывающий сокет для сервера и считывающий данные с него синхронно. Когда строка String thisLine = aReadStream.ReadLine(); блокируется из-за отсутствия данных для чтения из сокета, и я пытаюсь выполнить Thread.Abort для уничтожения потока (поскольку он заблокирован в этом ReadLine ()), я ожидаю, что смогу перехватить 1003 * НО Не могу.

Поток остается заблокированным на этом 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 ]

2 голосов
/ 03 марта 2010

Закройте розетку из другого потока. Это должно вызвать исключение SocketException, когда ReadLine заблокирован.

0 голосов
/ 13 апреля 2015

Не используйте StreamReader с сетевыми потоками. Это просто не работает с бесконечными потоками.

Что касается того, почему Thread.Abort не работает, это действительно просто - Thread.Abort работает только тогда, когда поток находится в состоянии WaitSleepJoin или аналогичном. Если поток работает, он имеет в управляемом коде - скорее всего, в неуправляемом коде выполняется блокирующий вызов сокета (/ blocking), поэтому Abort не может работать, пока не вернется. Нет способа «убить» поток - самая маленькая вещь, которую можно (более или менее) безопасно убить, - это процесс.

Именно поэтому Thread.Abort волшебным образом начинает работать, если впоследствии вы закроете сокет - это разблокирует поток и заставит его вернуться к управляемому коду, где Thread.Abort может совершить свое волшебство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...