gpt4 book ai didi

c# - 后台任务中的异步调用不起作用

转载 作者:太空宇宙 更新时间:2023-11-03 15:12:19 26 4
gpt4 key购买 nike

在我的应用程序中,我需要在后台扫描 Wi-Fi 接入点。我能够启动任务并初始化 Wi-Fi 适配器,但下一个执行扫描的异步调用“await scanner.ScanForNetworks()”似乎永远无法完成任务。会不会是大量嵌套异步调用的结果?如果是这样,有什么可能的解决方法?

扫描任务.cs

namespace BackgroundTaskLibrary
{
public sealed class ScanningTask : IBackgroundTask
{
private BackgroundTaskDeferral deferral;
private WiFiScanner scanner = new WiFiScanner();
private Windows.Storage.ApplicationDataContainer localSettings;
private DispatcherTimer timer;

public async void Run(IBackgroundTaskInstance taskInstance)
{
deferral = taskInstance.GetDeferral();
taskInstance.Canceled += TaskInstance_Canceled;
await scanner.InitializeFirstAdapter();
ShowToastNotification("Hi", "Hello from background"); //notification is shown

await scanner.ScanForNetworks();
ShowToastNotification("Hi", "Hello from background1"); //this one never gets shown
deferral.Complete();
}

private void TaskInstance_Canceled(IBackgroundTaskInstance sender,
BackgroundTaskCancellationReason reason)
{
deferral.Complete();
}

private void ShowToastNotification(string title, string stringContent)
{
ToastNotifier ToastNotifier = ToastNotificationManager.CreateToastNotifier();
Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
Windows.Data.Xml.Dom.XmlNodeList toastNodeList = toastXml.GetElementsByTagName("text");
toastNodeList.Item(0).AppendChild(toastXml.CreateTextNode(title));
toastNodeList.Item(1).AppendChild(toastXml.CreateTextNode(stringContent));
Windows.Data.Xml.Dom.IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
Windows.Data.Xml.Dom.XmlElement audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-winsoundevent:Notification.SMS");

ToastNotification toast = new ToastNotification(toastXml);
toast.ExpirationTime = DateTime.Now.AddSeconds(10);
ToastNotifier.Show(toast);
}
}
}

WiFi适配器.cs

namespace BackgroundTaskLibrary
{
class WiFiScanner
{
//WiFi adapter instance
public WiFiAdapter WiFiAdapter { get; private set; }
public Geolocator _geolocator = new Geolocator();
public Geoposition Location { get; set; }

/// <summary>
/// Find the fisrts available WiFi adapter and initialise it
/// </summary>
/// <returns></returns>
public async Task InitializeFirstAdapter()
{
var access = await WiFiAdapter.RequestAccessAsync();
if (access != WiFiAccessStatus.Allowed)
{
throw new Exception("WiFiAccessStatus not allowed");
}
else
{
var wifiAdapterResults =
await DeviceInformation.FindAllAsync(WiFiAdapter.GetDeviceSelector());
if (wifiAdapterResults.Count >= 1)
{
this.WiFiAdapter =
await WiFiAdapter.FromIdAsync(wifiAdapterResults[0].Id);
}
else
{
var dialog = new MessageDialog("WiFi Adapter not found.");
await dialog.ShowAsync();

throw new Exception("WiFi Adapter not found.");
}
}
}

public async Task ScanForNetworks()
{
if (WiFiAdapter != null)
{
await WiFiAdapter.ScanAsync();
}
else
{
throw new Exception("No Wi-Fi adapter");
}

Location = await _geolocator.GetGeopositionAsync();

List<AccessPoint> accessPoints = new List<AccessPoint>();
foreach(var network in WiFiAdapter.NetworkReport.AvailableNetworks)
{
AccessPoint ap = new AccessPoint()
{
SSID = network.Ssid,
Mac = network.Bssid,
SignalStrength = network.NetworkRssiInDecibelMilliwatts,
Open = (int)network.SecuritySettings.NetworkAuthenticationType
};

accessPoints.Add(ap);
}
await SaveData(accessPoints);

}

public async Task SaveData(List<AccessPoint> accessPoints)
{
string info = DateTime.Now + "|" + Location.Coordinate.Point.Position.Latitude
+ "|" + Location.Coordinate.Point.Position.Longitude + "|";
for (int i = 0; i < accessPoints.Count; i++)
{
info += accessPoints[i].ToString();
}

info += Environment.NewLine;

// Get the logical root folder for all external storage devices.
StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;

// Get the first child folder, which represents the SD card.
StorageFolder sdCard = (await externalDevices.GetFoldersAsync()).FirstOrDefault();


StorageFile infoFile;

if (sdCard != null)
{
//check if info file exists
try
{
infoFile = await sdCard.GetFileAsync("wifiScanInfo.txt");
}
catch
{
infoFile = await sdCard.CreateFileAsync("wifiScanInfo.txt");
}

await FileIO.AppendTextAsync(infoFile, info);
}
}
}
}

如果您需要整个项目:https://www.dropbox.com/sh/1v9mbr3xhgr3283/AACDbB7skZUI7Z5fiu0HT8r4a?dl=0

编辑:

通过随后简化 ScanningTask,我能够确定问题出在调用“await WiFiAdapter.ScanAsync();”

我终于设法从“await WiFiAdapter.ScanAsync();”捕获了一个异常,这里是堆栈跟踪:

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

at BackgroundTaskLibrary.WiFiScanner.<ScanForNetworks>d__10.MoveNext()

但是扫描已完成并且结果按预期保存在文本文件中。我可能缺少哪些权限?我已声明互联网、位置和可移动存储权限。

最佳答案

它认为异常来自在没有调用 requestAccessAsync 的情况下使用 GeoLocator :

Starting in Windows 10, call the RequestAccessAsync before accessing the user’s location. At that time, your app must be in the foreground and RequestAccessAsync must be called from the UI thread. Until the user grants your app permission to their location, your app can't access location data.

来源:https://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.geolocation.geolocator.aspx?f=255&MSPPError=-2147217396

关于c# - 后台任务中的异步调用不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40606322/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com