首页 > 解决方案 > WiFiAdapter.ScanAsync() 在失去已建立的 WiFi 连接后失败

问题描述

我正在为 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 可用,我使用“await WiFiAdapter.ConnectAsync()”连接到它,它工作得很好(我通过将 HoloLens 连接到我的智能手机的热点来检查它)。

现在到错误:

正在使用 HoloLens 连接到我的热点。如果我随后禁用我的热点,HoloLens 将失去连接,但会继续扫描并列出可用网络。如果我然后重新打开热点,“await WiFiAdapter.ScanAsync()”方法将需要大约 20 秒,然后失败并抛出类似于“操作中止,...TaskAwaiter.ThrowForNonSuccess”的异常(我制作了一个屏幕截图显示异常的内容)。

ScanAsync() 抛出异常

如果没有 try/catch,这会导致我的 async Task Scan() 退出而没有最终将我的布尔 IsReady 设置回 true,然后导致我的应用程序不再扫描可用网络。问题是,我当前的解决方案只不过是一个实际可行的简单解决方法,但实际上并没有解决我在使用 ScanAsync 方法时遇到的问题。

我只是不明白为什么它会这样。WiFiAdapter 可用,所以这可能不是问题。有没有办法检查我与所需网络的已建立连接是否丢失(就像我打开热点时一样)?或者有没有办法告诉“await ScanAsync”方法在需要太长时间时提前取消?我很高兴你们的每一个想法!

问候BB

-编辑-

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

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

标签: c#uwpasync-awaithololens

解决方案


推荐阅读