Я работаю с Windows.Devices.WiFi API для приложения UWP HoloLens. Я сканирую доступные сети как можно чаще (вызывая Scan () для каждого кадра), используя логическое значение, для которого задано значение false прямо перед вызовом «await ScanAsync ()», и установлено значение 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» (я сделал снимок экрана, показывающий содержание исключения).
Без try / catch это привело к закрытию моего асинхронного сканирования задач () без окончательной установки моего логического значения IsReady обратно в true, что привело к тому, что мое приложение больше не сканировало доступные сети.
Проблема в том, что мое текущее решение - не что иное, как простой обходной путь, который на самом деле работает, но на самом деле не решает проблему, с которой я сталкиваюсь при использовании метода ScanAsync.
Я просто не могу понять, почему он так себя ведет. WiFiAdapter доступен, так что это, вероятно, не проблема.
Есть ли способ проверить, не утрачено ли мое установленное соединение с желаемой сетью (например, когда я выключаю свою точку доступа)?
Или есть способ сказать "ожидайте ScanAsync", чтобы отменить раньше, если это занимает слишком много времени?
Я рад за каждую идею о вас, ребята!
Поздравления
* 1019 Синяя книга *
-EDIT-
Мой полный класс выглядит следующим образом, и я создаю его один раз в другом скрипте, где затем вызываю необходимые функции.
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;
}
}
}