C# Handling threads and blocking sockets
In the following thread, UDP packets are read from clients until the boolean field Run is set to false.
If Run is set to false while the Receive method is blocking, it stays blocked forever (unless a client sends data, which will make the thread loop and check for the Run condition again).
while (Run)
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] data = udpClient.Receive(ref remoteEndPoint); // blocking method
// process received data
}
I usually get around the problem by setting a timeout on the server. It works fine, but seems to be a patchy solution to me.
udpClient.Client.ReceiveTimeout = 5000;
while (Run)
{
try
{
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] data = udpClient.Receive(ref remoteEndPoint); // blocking method
// process received dat开发者_高级运维a
}
catch(SocketException ex) {} // timeout reached
}
How would you handle this problem? Is there any better way?
Use UdpClient.Close(). That will terminate the blocking Receive() call. Be prepared to catch the ObjectDisposedException, it signals your thread that the socket is closed.
You could do something like this:
private bool run;
public bool Run
{
get
{
return run;
}
set
{
run = value;
if(!run)
{
udpClient.Close();
}
}
}
This allows you to close the client once whatever condition is met to stop your connection from listening. An exception will likely be thrown, but I don't believe it will be a SocketTimeoutException, so you'll need to handle that.
精彩评论