簡體   English   中英

后台任務中的異步調用不起作用

[英]Async call in background task doesn't work

在我的應用中,我需要在后台掃描Wi-Fi接入點。 我能夠啟動任務並初始化Wi-Fi適配器,但是下一個異步調用“ await scan.ScanForNetworks()”來執行掃描似乎從未完成任務。 可能是大量嵌套異步調用的結果嗎? 如果是這樣,可能有什么解決方法?

ScanningTask.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);
        }
    }
}

WiFiAdapter.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()

但是,掃描已完成,結果已按預期保存在文本文件中。 我可能缺少哪些權限? 我已經聲明了Internet,位置和可移動存儲權限。

它認為異常來自使用GeoLocator而沒有requestAccessAsync調用:

從Windows 10開始,在訪問用戶位置之前調用RequestAccessAsync。 那時,您的應用必須位於前台,並且必須從UI線程調用RequestAccessAsync。 在用戶向您的應用授予其位置權限之前,您的應用無法訪問位置數據。

來源: https : //msdn.microsoft.com/zh-cn/library/windows/apps/windows.devices.geolocation.geolocator.aspx?f=255&MSPPError=-2147217396

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM