我有一个C#代码,在Windows Vista / 7中非常有效,但在Windows XP上却没有。
有问题的部分是“多播”节点,该节点基本上是通过多播地址+端口读取和发送数据的。
正在读取/写入网络的部分是单例。
访问此单例的每个线程都必须指出何时需要开始收听以及何时停止。
[当至少一个线程需要“启动”时,侦听套接字,而当所有线程“停止”时,我们都停止(它们必须提供一个Guid令牌,即Start方法返回)。
此启动/停止机制是为了确保如果没有线程需要查看网络上正在发生的事情,我们不会为此而消耗内存。
我遇到的问题是,在Windows XP上,出现了此异常:
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)
经过一番搜索后,看起来在Windows XP及更低版本上,当线程结束时,操作系统将释放其所有I / O资源。 (VB.NET 3.5 SocketException on deployment but not on development machine)。
是否有避免这种行为的方法?因为就我而言,这是正常现象,通常我创建一个线程,该线程将在执行结束之前结束,并且我不想释放其套接字?
如果不可能,您将如何处理?
在幕后,整个过程基于称为重叠I / O的事物。在Windows Vista中,更改了重叠I / O的行为,因此当调用线程中止时,I / O操作不再被取消。
在Windows Vista(例如XP)之前,每当调用线程中止此线程启动的任何重叠I / O时,都会被取消,这可能是此异常的原因。
您可以在此处了解更多信息:http://www.lenholgate.com/blog/2008/02/major-vista-overlapped-io-change.html
您无法覆盖此行为,但是可以确保(例如,使用事件)您不会尝试使用任何I / O资源,从而创建线程不再处于活动状态。
IsBackground
属性设置为true,该线程在BlockingCollection上进行迭代。当我需要再听一个IP时,我将此IP添加到阻塞集合中,然后该线程创建它。由于此线程在整个应用程序生命周期中永无止境,因此不会释放资源。我已经通过检查Environment.OSVersion.Version.Major
是否大于或等于6(即Vista版本号)来进行此操作。
现在,它在所有版本上都像护身符一样工作>>