我正在使用适用于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" (我制作了截图,显示了异常的内容)。
没有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;
}
}
}