我正在创建一个运行UDP客户端接收消息的线程,在收到消息后我要关闭UDP客户端然后结束线程,但我不知道如何结束线程,因为“接收”一直运行直到得到答案。
到目前为止,这是我的代码:
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();
答案 0 :(得分:6)
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
返回一个布尔值,指示它是否已关闭(当然忽略了您的线程只接收一条消息的事实)。
答案 1 :(得分:2)
而不是Receive()
,您可以使用BeginReceive()
/ EndReceive()
- 它是异步替代方案。
请参阅MSDN:http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive.aspx
这些方法使用.NET的常见APM(异步编程模型)。
答案 2 :(得分:2)
如果要在继续当前线程之前等待它结束,可以使用
recieveDataThread.Join();
否则,一旦最后一行完成,线程就会关闭。
如果您想提前结束,可以使用
recieveDataThread.Abort();
来自另一个主题。
答案 3 :(得分:0)
我一直在寻找良好的答案,并感谢同事根据以下解决方案提出的建议(似乎可以正常工作)
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。它可以正常工作。
答案 4 :(得分:0)
对Jacek以上解决方案的改进是使用了第二个while循环;这样做不会导致超时触发时不会丢弃正在接收的可能的数据报(原始代码在每次超时时都会调用另一个ReceiveAsync,而忽略任何正在进行的Receive):
while (_monitoringThreadIsRunning {
var receiveTask = _udpClient.ReceiveAsync();
while (_monitoringThreadIsRunning {
var timeoutTask = Task.Delay(ReceiveTimeout);
if (timeoutTask == await Task.WhenAny(timeoutTask, receiveTask))
continue;
UdpReceiveResult udpReceiveResult = await receiveTask;
// handle udpReceiveResult.Buffer
break; // return to outer loop, launching another Receive
}
}
PS:我本来应该对此发表评论,但是由于这是我在这里的第一个贡献,所以我缺乏这样做的必要声誉。