仅在Windows XP上异步接收时UdpClient异常

问题描述 投票:2回答:4

我有一个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)。

是否有避免这种行为的方法?因为就我而言,这是正常现象,通常我创建一个线程,该线程将在执行结束之前结束,并且我不想释放其套接字?

如果不可能,您将如何处理?

c# .net sockets windows-xp udpclient
4个回答
2
投票
异步I / O操作使用称为IOCP(I / O完成端口)的机制在I / O操作结束时通知执行线程。

在幕后,整个过程基于称为重叠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资源,从而创建线程不再处于活动状态。


1
投票
所以,我的解决方法是让一个线程将IsBackground属性设置为true,该线程在BlockingCollection上进行迭代。当我需要再听一个IP时,我将此IP添加到阻塞集合中,然后该线程创建它。

由于此线程在整个应用程序生命周期中永无止境,因此不会释放资源。我已经通过检查Environment.OSVersion.Version.Major是否大于或等于6(即Vista版本号)来进行此操作。

现在,它在所有版本上都像护身符一样工作>>


0
投票

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.