失去已建立的WiFi连接后,WiFiAdapter.ScanAsync()失败

时间:2018-05-14 07:12:10

标签: c# uwp async-await hololens

我正在使用适用于UWP HoloLens应用程序的Windows.Devices.WiFi API。我正在尽可能频繁地扫描可用的网络(每帧调用Scan()),在调用" await ScanAsync()"之前使用一个设置为false的布尔值,异步完成后设置为true,这导致每次完成时调用ScanAsync(),效果很好。像这样:

public async Task Scan()
{
    if (IsReady)
    {       
        IsReady = false;
        try
        {
            await MyWiFiAdapter.ScanAsync();
        }
        catch(Exception e)
        {
            string fail = e.ToString();
            Success = false;
        }
        IsReady = true;
    }
}

如果我所需的SSID可用,我使用"等待WiFiAdapter.ConnectAsync()"连接到它,它工作得很好(我通过将HoloLens连接到一个热点来检查它)我的智能手机)。

现在来看错误:

使用HoloLens连接到我的热点正在运行。如果我然后禁用我的热点,HoloLens将失去连接,但继续扫描并列出可用的网络。 如果我重新打开我的热点,方法"等待WiFiAdapter.ScanAsync()"将花费大约20秒,然后失败并抛出一个异常,例如"操作中止,... TaskAwaiter.ThrowForNonSuccess" (我制作了截图,显示了异常的内容)。

Thrown exception of ScanAsync()

没有try / catch,这导致我的异步任务扫描()退出而没有最终将我的布尔IsReady设置回true,这导致我的应用程序不再扫描可用的网络。 问题是,我目前的解决方案只不过是一个实际有效的简单解决方法,但实际上并没有解决我使用ScanAsync方法的问题。

我无法弄清楚它为什么会这样。有一个WiFiAdapter,所以这可能不是问题。 有没有办法检查我与所需网络建立的连接是否丢失(就像我关闭热点时一样)? 或者有没有办法告诉"等待ScanAsync"如果花费的时间太长,可以提前取消? 我很满意你们的每一个想法!

问候 B.B。

- 编辑 -

我的完整类看起来像这样,我在另一个脚本中实例化它,然后我调用必要的函数。

using Assets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.WiFi;
using Windows.Networking.Connectivity;


namespace Assets
{
    public class UniversalWiFi : IWiFiAdapter
    {
        private bool Success { get; set; }
        private WiFiConnectionStatus MyConnectionStatus;
        private bool IsReady { get; set; }
        private bool InitialConnection { get; set; }
        private uint Signal { get; set; }
        private string Report { get; set; }
        private string DesiredSsid { get; set; }
        private string ConnectedSsid { get; set; }
        private WiFiAdapter MyWiFiAdapter { get; set; }
        private bool ReadyToConnect { get; set; }

        public UniversalWiFi()
        {
            InitialConnection = true;
            Success = false;
            IsReady = true;
            ReadyToConnect = true;
            Signal = 0u;
            DesiredSsid = "Desired SSID not yet defined";
            ConnectedSsid = string.Empty;
            Report = string.Empty;
        }

        public bool GetSuccess()
        {
            return Success;
        }

        public string GetNameOfConnectedSsid()
        {
            try
            {
                var connected = NetworkInformation.GetInternetConnectionProfile().WlanConnectionProfileDetails.GetConnectedSsid();
                if (connected != null)
                {
                    ConnectedSsid = connected;
                }
                else
                {
                    ConnectedSsid = string.Empty;
                }
            }
            catch
            {
                ConnectedSsid = string.Empty;
            }
            return ConnectedSsid;
        }

        public uint GetSignal(string ssid)
        {
            DesiredSsid = ssid;
            return Signal;
        }

        private async Task InitiateGetAdapterAsync()
        {
            var result = await WiFiAdapter.FindAllAdaptersAsync();
            if (result.Count >= 1)
            {
                MyWiFiAdapter = result[0];
            }
            InitialConnection = false;
        }

        public async Task Scan()
        {
            if (IsReady)
            {       
                IsReady = false;
                uint signal = 0u;
                    if (MyWiFiAdapter == null)
                    {
                        try
                        {
                            await InitiateGetAdapterAsync();
                        }
                        catch
                        {
                            MyWiFiAdapter = null;
                        }
                    }
                    else
                    {
                        try
                        {
                            await MyWiFiAdapter.ScanAsync();

                            GenerateNetworkReport(MyWiFiAdapter.NetworkReport);

                            if (!string.IsNullOrEmpty(DesiredSsid) && DesiredSSIDExists(MyWiFiAdapter.NetworkReport))
                            {
                                signal = GetNetworkSignal(MyWiFiAdapter.NetworkReport, DesiredSsid);
                                var desiredNW = MyWiFiAdapter.NetworkReport.AvailableNetworks.Where(y => y.Ssid == DesiredSsid).FirstOrDefault();
                                if ((ConnectedSsid != DesiredSsid) && (desiredNW != null))
                                {
                                    if ((await MyWiFiAdapter.ConnectAsync(desiredNW, WiFiReconnectionKind.Manual)).ConnectionStatus == WiFiConnectionStatus.Success) //ReconnectionKind entspricht dem Häkchen "automatisch verbinden" in den Windows Einstellungen
                                    {                                                                                                                                //"Manual" da sich die HoloLens sonst teilweise über die App stellt und selbstständig verbindet
                                        Success = true;
                                    }
                                    else
                                    {
                                        Success = false;
                                    }
                                }
                            }
                            else
                            {
                                Success = false;
                            }
                        }
                        catch(Exception e)
                        {
                            string fail = e.ToString();
                            Success = false;
                        }
                    }
                IsReady = true;
                Signal = signal;
            }

        private bool DesiredSSIDExists(WiFiNetworkReport report)
        {
            var networks = new List<string>();
            foreach (var network in report.AvailableNetworks)
            {
                networks.Add(string.Format("SSID: {0} -- SignalBars: {1} -- Db: {2} -- Mac: {3}",
                    network.Ssid, network.SignalBars, network.NetworkRssiInDecibelMilliwatts, network.Bssid));
            }
            var match = networks.FirstOrDefault(stringToCheck => stringToCheck.Contains(DesiredSsid));

            if (match != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private uint GetNetworkSignal(WiFiNetworkReport report, string ssid)
        {
            var network = report.AvailableNetworks.Where(x => x.Ssid.ToLower() == ssid.ToLower()).FirstOrDefault();
            if (network != null)
            {
                return network.SignalBars;
            }
            else
            {
                return 0u;
            }
        }

        private void GenerateNetworkReport(WiFiNetworkReport report)
        {
            var networks = new List<string>();
            foreach (var network in report.AvailableNetworks)
            {
                networks.Add(string.Format("SSID: {0} -- SignalBars: {1} -- Db: {2} -- Mac: {3}",
                    network.Ssid, network.SignalBars, network.NetworkRssiInDecibelMilliwatts, network.Bssid));
            }

            Report = string.Join(Environment.NewLine, networks.ToArray());
        }

        public string GetNetworkReport()
        {
            return Report;
        }
    }
}

0 个答案:

没有答案