使用托管API关闭WiFi连接

我正在使用Managed WiFi API编写程序。 以下是我获取范围内所有网络的方法:

void UpdateNetworks() { networks = new List(); WlanClient client = new WlanClient(); foreach(WlanClient.WlanInterface iface in client.Interfaces) { Wlan.WlanAvailableNetwork[] nets = iface.GetAvailableNetworkList(0); foreach(Wlan.WlanAvailableNetwork net in nets) networks.Add(net); } } 

问题是,在18次调用此方法后,我无法再连接:

(0x80004005):尝试建立与网络服务器的会话,但已经为该服务器建立了太多会话。

这是抛出exception的构造函数:

  public WlanClient() { Wlan.ThrowIfError( Wlan.WlanOpenHandle(Wlan.WLAN_CLIENT_VERSION_XP_SP2, IntPtr.Zero, out negotiatedVersion, out clientHandle)); try { Wlan.WlanNotificationSource prevSrc; wlanNotificationCallback = new Wlan.WlanNotificationCallbackDelegate(OnWlanNotification); Wlan.ThrowIfError( Wlan.WlanRegisterNotification(clientHandle, Wlan.WlanNotificationSource.All, false, wlanNotificationCallback, IntPtr.Zero, IntPtr.Zero, out prevSrc)); } catch { Wlan.WlanCloseHandle(clientHandle, IntPtr.Zero); throw; } } 

我相信这是因为客户端永远不会关闭它打开的连接。 如何明确关闭它们? catch块中的句柄关闭,但它需要访问客户端的私有部分。

由于您只是在经过一定次数的迭代后才发现问题,因此问题可能是某种资源耗尽,这听起来资源没有得到及时清理。

从上面的评论中,听起来你没有处理你的WlanClient实例,这可能是问题的一部分(或全部)。 我可以理解你为什么不处理它们,因为它们没有给你任何明显的方法。 这似乎是一个真正有问题的设计。 有各种各样的设计指南,说像这样的类应该给你一个公共Dispose方法或一个公共Close方法,但即使他们有这两种方法,他们故意使它们都是私有的。

但该类确实实现了IDisposable ,因此您仍然可以通过添加using块来清理它:

 using (var wlanClient = new WlanClient()) { .... } // wlanClient will be disposed when flow leaves the block 

这将确保在流离开using块的时刻​​清除所有对象的资源(即使流程因为存在exception而离开)。 您的连接将被关闭,您的非托管内存将被释放,以及其他任何需要发生的事情。

我也有同样的问题。 我尝试了Joe White先生的解决方案但是我收到了一个错误,即wlanClient无法转换为System.IDisposable。
由于这个问题与WlanClient实例的处理有关,我只将1个实例定义为类成员,并在方法[void UpdateNetworks()]中多次使用它。 我没有收到任何错误。
删除行

 WlanClient client = new WlanClient(); 

从您的方法中,并在您的类中定义它。 如下:

 public partial class frm_main : Form { private WlanClient client = new WlanClient(); private void UpdateNetworks() { var networks = new List(); foreach (WlanClient.WlanInterface iface in client.Interfaces) { Wlan.WlanAvailableNetwork[] nets = iface.GetAvailableNetworkList(0); foreach (Wlan.WlanAvailableNetwork net in nets) networks.Add(net); } MessageBox.Show(networks.Count.ToString()); } } 

参考: 托管WiFi错误