Закрытие WiFi-подключений с помощью управляемого API - PullRequest
2 голосов
/ 04 июня 2011

Я пишу программу, используя Управляемый 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 есть ручка закрытия, но для этого требуется доступ к закрытым частям клиента.

Ответы [ 2 ]

4 голосов
/ 07 декабря 2013

У меня такая же проблема.Я попробовал решение для мистера Джо Уайта, но получил ошибку, что 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 голосов
/ 04 июня 2011

Поскольку вы видите проблемы только после определенного количества итераций, проблема, скорее всего, заключается в исчерпании ресурсов какого-либо рода, что звучит так, как будто ресурсы не очищаются своевременно.

Из приведенных выше комментариев кажется, что вы не утилизируете свои WlanClient экземпляры, которые могут быть частью (или всеми) проблемы. Я могу понять, почему вы не избавляетесь от них, потому что они не дают вам никакого очевидного способа сделать это. Это кажется действительно проблематичным дизайном с их стороны. Существуют всевозможные руководящие принципы проектирования, в которых говорится, что подобный класс должен давать вам либо публичный Dispose метод, либо публичный Close метод, но хотя они и имеют оба этих методов, они намеренно сделали их оба частные.

Но класс реализует IDisposable, так что вы все еще можете очистить его, добавив блок using:

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

Это обеспечит очистку всех ресурсов объекта в тот момент, когда поток покидает блок using (даже если поток уходит из-за исключения). Ваши соединения будут закрыты, ваша неуправляемая память освобождена, и все, что еще должно произойти.

...