使用托管 API 关闭 WiFi 连接

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

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

    void UpdateNetworks()
    {
        networks = new List<Wlan.WlanAvailableNetwork>();
        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):已尝试 建立与网络的会话 服务器,但已经太多了 与该服务器建立的会话。

这是抛出异常的构造函数:

    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
块中有句柄关闭,但它需要访问客户端的私有部分。

c# wifi
2个回答
4
投票

我也有同样的问题。 我尝试了 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<Wlan.WlanAvailableNetwork>();
         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 错误


2
投票

由于您仅在一定次数的迭代后才会看到问题,因此问题可能是某种资源耗尽,这听起来像是资源没有及时清理。

从上面的评论来看,听起来您没有处理您的

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

但是该类确实实现了

IDisposable
,因此您仍然可以通过添加
using
块来清理它:

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

这将确保在流离开

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

© www.soinside.com 2019 - 2024. All rights reserved.