Hui
Hui

Reputation: 14457

Closing WiFi connections using the Managed API

I'm writing a program using the Managed WiFi API. Here's how I get all the networks in range:

    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);
        }
    }

The problem is that after 18 calls to this method I can no longer connect:

(0x80004005): An attempt was made to establish a session to a network server, but there are already too many sessions established to that server.

Here's the constructor that's throwing the 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;
        }
    }

I believe this is because the client never closes the connections it opens. How do I close them explicitly? There's handle closing in the catch block, but it requires access to the client's private parts.

Upvotes: 3

Views: 5635

Answers (2)

Sadegh Ameri
Sadegh Ameri

Reputation: 310

I have the same problem. I tried Mr Joe White solution but I received an error that wlanClient cannot be converted to System.IDisposable.
Since this problem is related to disposal of WlanClient instances, I only defined 1 instance as class member and used it so many times in method [void UpdateNetworks()]. I did not receive any error.
Remove line

WlanClient client = new WlanClient();

from your method and define it in your class. like the following:

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());
     }
}

Reference: Managed WiFi error

Upvotes: 4

Joe White
Joe White

Reputation: 97696

Since you're seeing problems only after a certain number of iterations, the problem is likely resource exhaustion of some sort, which sounds like resources aren't getting cleaned up in a timely manner.

From the comments above, it sounds like you're not disposing your WlanClient instances, which may be part (or all) of the problem. I can understand why you're not disposing them, though, because they don't give you any obvious way to do so. This seems like a really problematic design on their part. There are all kinds of design guidelines that say a class like this should give you either a public Dispose method or a public Close method, but even though they have both those methods, they deliberately made them both private.

But the class does implement IDisposable, so you can still clean it up by adding a using block:

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

This will make sure all of the object's resources get cleaned up at the moment flow leaves the using block (even if flow is leaving because there was an exception). Your connections will be closed, your unmanaged memory released, and whatever else needs to happen.

Upvotes: 2

Related Questions