UdpClient Exception on async reception only on Windows XP

2

I've a c# code that works very well in Windows vista/seven, but not on Windows XP.

The problematic part is a "multicast" node, that basically read and send data over a multicast address+port.

The part that is reading/writing to the network is a singleton.

Every thread that access to this singleton must indicate when they need to start to listen, and when they stop.

Socket are listened when at least one thread need to "Start", and we stop when all thread "Stop"(they have to give a Guid token, that the Start method return).

This start/stop mecanism is to ensure that if no thread need to see what is happening on the network, we don't consume memory for that.

The problem I got is that on windows XP, I got this exception:

System.Net.Sockets.SocketException (0x80004005): The I/O operation has been aborted because of either a thread exit or an application request
   at System.Net.Sockets.Socket.EndReceiveFrom(IAsyncResult asyncResult, EndPoint& endPoint)
   at System.Net.Sockets.UdpClient.EndReceive(IAsyncResult asyncResult, IPEndPoint& remoteEP)

After some search, it appears, that on windows XP and below, when a thread ends, the OS release all its I/O resources. (VB.NET 3.5 SocketException on deployment but not on development machine ).

Is there a way to avoid this behavior? Because in my case, it's normal and often that I create a thread that will ends before the end of the execution, and I don't want to have its socket released?

If it's not possible, how will you handle this?

c#
.net
sockets
windows-xp
udpclient
asked on Stack Overflow Mar 25, 2013 by J4N • edited May 23, 2017 by Community

3 Answers

2

The calling thread, of the async operation, is terminated before the operation completes.

Async I/O operation use mechanism called IOCP (I/O Completion Port) to notify the executing thread when the I/O operation ends.

Bhind the scenes, the whole thing based on something called Overlapped I/O. In Windows Vista the behavior of overlapped i/o was changed, so when the calling thread aborted the I/O operation is no longer cancelled.

Prior to Windows Vista (for example, XP), whenever the calling thread aborted any overlapped i/o initiated by this thread is cancelled, and probably this is the reason for this exception.

You can read more about it here: http://www.lenholgate.com/blog/2008/02/major-vista-overlapped-io-change.html

You can't override this behavior, but you can make sure (using events, for example) that you won't try to use any I/O resource that the creating thread is no longer active.

answered on Stack Overflow Mar 25, 2013 by Shahar Gvirtz
1

So it seems this is due to windows XP that release automatically resources created by a thread when the thread ends( VB.NET 3.5 SocketException on deployment but not on development machine ).

So, my workaround is to have a thread that has the IsBackground property set to true, that is iterating on a BlockingCollection. When I need to listen one more IP, I add this IP on the blocking collection and this thread creates it.

Since this thread never ends in the whole application life, the resources are not released. I've made this behavior checking the Environment.OSVersion.Version.Major to be bigger or equals to 6, which is the Vista version number.

Now it works like a charms onall versions

answered on Stack Overflow Apr 26, 2013 by J4N • edited May 23, 2017 by Community
0

On newer .NET FrameWork versions this will do the trick.

TaskEx.Run(() => _udp.BeginReceive(AsyncCallback, state)).ConfigureAwait(false);
answered on Stack Overflow May 19, 2015 by Mikko Viitala

User contributions licensed under CC BY-SA 3.0