Безопасное завершение потока при использовании UDP Receive - PullRequest
4 голосов
/ 03 февраля 2012

Я создаю поток, который запускает UDP-клиент, который получает сообщение, после того, как он получает сообщение, я хочу закрыть UDP-клиент и затем завершить поток, но я не знаю, как завершить поток, так как "Receive" всегда работает, пока не получит ответ.

Это мой код:

private void RecieveChallenge()
{
    UdpClient client = new UdpClient(26000);
    IPEndPoint remoteIp = new IPEndPoint(IPAddress.Any, 0);

    Byte[] receivedBytes = client.Receive(ref remoteIp);
    string ipAddress = Encoding.ASCII.GetString(receivedBytes);
}

Важной строкой является client.Receive (ref remoteIp);

Вот как я начинаю свою тему:

Thread recieveChallengeThread = new Thread(new ThreadStart(RecieveChallenge));
recieveDataThread.Start();

Ответы [ 4 ]

6 голосов
/ 03 февраля 2012

client.Receive вернет пустой byte[] при закрытии соединения. Вам просто нужно закрыть соединение и изменить предоставленный код на:

private void RecieveChallenge()
{
    UdpClient client = new UdpClient(26000);
    IPEndPoint remoteIp = new IPEndPoint(IPAddress.Any, 0);

    Byte[] receivedBytes = client.Receive(ref remoteIp);
    if (receivedBytes == null || receivedBytes.Length == 0)
        return;
    string ipAddress = Encoding.ASCII.GetString(receivedBytes);
}

Хотя вы, вероятно, захотите RecieveChallenge вернуть логическое значение, указывающее, закрыто оно или нет (конечно, игнорируя тот факт, что ваш поток будет когда-либо получать только одно сообщение).

2 голосов
/ 03 февраля 2012

Если вы хотите дождаться его окончания, прежде чем продолжить в текущем потоке, вы можете использовать

recieveDataThread.Join();

В противном случае поток закрывается, как только завершается последняя строка.

ЕслиВы хотите закончить это рано, вы можете использовать

recieveDataThread.Abort(); 

из другого потока.

2 голосов
/ 03 февраля 2012

Вместо Receive() вы можете использовать BeginReceive() / EndReceive() - это асинхронная альтернатива.

См. MSDN: http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive.aspx

В этих методах используется обычный APM(модель асинхронного программирования) .NET.

0 голосов
/ 26 октября 2018

Я искал хороший ответ, и благодаря совету коллеги я принял следующее решение (кажется, работает нормально)

while (_monitoringThreadIsRunning)
{                        
   var timeoutTask = Task.Delay(ReceiveTimeout);
   var receiveTask = _udpClient.ReceiveAsync();

   if (timeoutTask == await Task.WhenAny(timeoutTask, receiveTask))
      continue;

   UdpReceiveResult udpReceiveResult = await receiveTask;
   // handle udpReceiveResult.Buffer
}

Для остановки необходимо установить для _monitoringThreadIsRunning значение false.Работает без каких-либо исключений.

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