【问题标题】:Closing WiFi connections using the Managed API使用托管 API 关闭 WiFi 连接
【发布时间】:2011-09-08 11:23:48
【问题描述】:

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

【问题讨论】:

  • 即使在非特殊情况下,您是否确保致电WlanCloseHandle?你没有显示你的班级是否有Dispose(或者它是否被正确调用)。
  • 这不是我的课,它来自API,请查看链接以获取源代码。
  • 啊,好的。是的,它确实在其Dispose 中进行了清理。那么,您是否确保在您的 WlanClient 实例上调用Dispose?这是最明显的要检查的第一件事。
  • 编译器说客户端没有Dispose()方法。

标签: c# wireless


【解决方案1】:

我也有同样的问题。 我尝试了 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());
     }
}

参考:Managed WiFi error

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 'NativeWifi.WlanClient': type used in a using statement must be implicitly convertible to 'System.IDisposable'.
    • 你怎么知道它确实实现了IDisposable?源代码中没有说WlanClient : IDisposable
    • 嗯。我正在查看的代码(通过您问题中的链接)确实实现了 IDisposable。也许他们在您下载的版本之后更改了它? managedwifi.codeplex.com/SourceControl/changeset/view/…public class WlanClient : IDisposable
    • 是的,看起来是这样,它是在最新更改中添加的(仍然是两年前,我不知道我是如何获得早期版本的)。谢谢。
    • @HUI:请分享您调用 Connect(4 个参数)方法的代码部分...我收到错误,即参数不正确...请帮助...打破我的头 4 日
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多