правильный способ отменить заблокированную тему - PullRequest
5 голосов
/ 27 ноября 2011

Я создаю сервер с TCP-соединением. Соединение TCP выполняется в своем собственном потоке в течение неопределенного периода времени. Есть хороший шаблон для безопасного отключения TcpListener и Client, а также потока? Ниже то, что я имею до сих пор.

private volatile bool Shudown;

void ThreadStart1()
{
    TcpListener listener = null;
    TcpClient client = null;
    Stream s = null;
    try
    {
        listener = new TcpListener(60000);
        client = listener.AcceptTcpClient();
        Stream s = client.GetStrea();
        while(!Shutdown)  // use shutdown to gracefully shutdown thread.
        {
            try
            {
                string msg = s.ReadLine();  // This blocks the thread so setting shutdown = true will never occur unless a client sends a message.
                DoSomething(msg);
            }
            catch(IOException ex){ } // I would like to avoid using Exceptions for flow control
            catch(Exception ex) { throw; }
        }
    }
    catch(Exception ex)
    {
        LogException(ex);
        throw ex;
    }
    finally
    {
        if(listener != null) listener.Close();
        if(s != null) s.Close();
        if(client != null) client.Close();
    }
}

Ответы [ 3 ]

5 голосов
/ 27 ноября 2011

Установить время ожидания для NetworkStream (client.ReadTimeout = ...). По истечении времени операции чтения проверьте, не сигнализировал ли основной поток о прекращении (установив переменную или AutoResetEvent). Если это было сигнализировано, чтобы остановить, выйдите изящно. Если нет, попробуйте прочитать снова до следующего тайм-аута.

Достаточно установить тайм-аут на 0,5 или 1 секунду - вы сможете своевременно выйти из потока, но при этом использовать процессор очень просто.

2 голосов
/ 27 ноября 2011

Есть ли хороший шаблон для безопасного отключения потока?

Измените цикл while на следующее:

while (!interrupted){
   // Do something
}
// declare interrupted as volatile boolean
volatile bool interrupted;

Проверьте это MSDN пример для подробностей. Если для прерывистого логического значения установлено значение true, поток выйдет из цикла при проверке условия while.

Есть ли хороший шаблон для безопасного отключения TcpListener и Клиент

Чтобы избежать дублирования, пожалуйста, отметьте этот ТАК вопрос

Что касается вашего вопроса о том, как прекратить блокирующий поток на ReadLine();, то следующий listener.Server.Close(); должен выполнить работу и вернуться из вызова блокировки.

1 голос
/ 28 ноября 2011

Возможно, вместо синхронного вызова Read для объекта NetworkStream, вы должны использовать BeginRead и EndRead, чтобы сделать это асинхронно, и вызвать Close () для NetworkStream, когда вы закончите с ним.

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