Прерывание потока, ожидающего оператора Read () (программирование сокетов C #) - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть приложение WinForms для клиента TCP-IP.Как только клиент подключается к локальному серверу, я запускаю поток t1, который входит в бесконечный цикл, чтобы продолжать получать сообщения от сервера.

Когда сервер не отправляет никакого сообщения, тогда поток бесконечно ждет в операторе m_DeviceServerStream.Read(instream, 0, buffersize);, как показано в коде ниже.

Thread t1;
TcpClient m_DeviceClientSocket = new TcpClient();
    NetworkStream m_DeviceServerStream = default(NetworkStream);

public void StartClient()
{
    m_DeviceClientSocket.Connect(m_DeviceURL, m_DevicePort);
    m_DeviceServerStream = m_DeviceClientSocket.GetStream();

    t1 = = new Thread(KeepReceiveingMessages);
    t1.Start();
}

public void StopClient() //On Stop Button-click
{
    t1.Abort();
}

public void KeepReceiveingMessages()
{
    while(true)
    {
        _dataServiceConnected.Waitone()
        try
        {
            var buffersize = m_DeviceClientSocket.ReceiveBufferSize;
            byte[] instream = new byte[buffersize];

            m_DeviceServerStream.Read(instream, 0, buffersize) //THREAD T1 KEEP WAITING HERE TILL A MESSAGE IS RECEIVED FROM THE SERVER
        }
        catch(Exception e)
        {                       
           _dataServiceConnected.Reset(); //do not try to eneter again till we have a working connection
        }
    }
}

Вопрос: Если я захочу закрыть клиентское приложение, тогда я хочу закончить нить изящно.Но я обнаружил, что даже если я вызываю t1.Abort(), поток t1 продолжает работать (как показано в окне отладки потоков Visual Studio). Прекращение потока не является хорошей практикой , так как мне завершить поток?

1 Ответ

0 голосов
/ 26 сентября 2019

Вы должны использовать WaitOne (Int32) для ожидания с таймаутом.Если WaitOne (int32) возвращает false, это означает, что истекло время ожидания, и событие не сигнализируется.Затем вы можете проверить, нужно ли вам любезно выйти из потока.

private bool volatile shouldCancel; //Dirty, but will work on Intel hardware :-)

public void KeepReceiveingMessages()
{
    while(true)
    {
        bool signaled = _dataServiceConnected.Waitone(100);
        if (!signaled && shouldCancel) return;
        try
        {
            var buffersize = m_DeviceClientSocket.ReceiveBufferSize;
            byte[] instream = new byte[buffersize];

            m_DeviceServerStream.Read(instream, 0, buffersize) //THREAD T1 KEEP WAITING HERE TILL A MESSAGE IS RECEIVED FROM THE SERVER
        }
        catch(Exception e)
        {                       
           _dataServiceConnected.Reset(); //do not try to eneter again till we have a working connection
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...