HttpClient无法在最小化的UWP App中执行GetAsync

时间:2018-08-08 17:32:48

标签: c# uwp

我正在研究一个项目,在其中播放几个视频。为了能够播放这些视频,我需要在应用程序通过HttpClient的{​​{1}}要求下获取其数据。一切正常,当UWP应用程序处于前台时,它会从Internet下载所需的信息。

应用程序离开前台并被用户System.Net.Http最小化时,无论它是来自HttpClient名称空间还是System.Net.Http名称空间的,均不起作用。我什至尝试在此处设置一个断点,并且前进Windows.Web.Http不会对HttpClient方法作出响应,并停留在该位置而不会返回任何结果,除非您再次激活该应用程序,然后它返回任何值。我不能使用await client.GetAsync(),因为它们需要BackgroundTasks,但我需要按需访问数据。

我还阅读了this条描述请求Triggers的文章,但结果仍然相同。当应用程序收到播放项目列表的请求时,我请求此状态。即使得到的结果为ExtendedExecutionStateAllowed的行为也与上述相同。

有没有一种方法可以在被请求时执行与互联网相关的查询并获得一些信息?

我执行的用于从Internet访问数据的代码是:

HttpClient

然后分析返回的值以从中获取所需的数据。

执行以请求public static async Task<string> GetResponseDataFromAPI(string apiRequestUrl, CancellationTokenSource cts = default) { cts = cts ?? new CancellationTokenSource(TimeSpan.FromSeconds(20)); try { var responseData = await AuthRequestHelper.globalHttpClient.GetAsync(apiRequestUrl, cts.Token); var result = await responseData.Content.ReadAsStringAsync(); return result; } catch (Exception ex) { INotifyHelper.iNotifyObject.IsVideoLoading = false; INotifyHelper.iNotifyObject.IsDataLoading = false; // show error return "{ \"error\": {\"code\": " + $"\"{ex.HResult}\", \"message\": \"{ex.Message}\"" + "} }"; } } 的代码是:

ExtendedExecutionSession

在最小化状态下,可以执行任何操作来执行请求的操作吗?指出正确方向的一点帮助将不胜感激。谢谢

2 个答案:

答案 0 :(得分:1)

BackgroundTransfer classes专为在后台挂起或关闭应用程序而在后台下载数据。

HttpClient最好用于非常短的下载,这些下载将很快完成。对于诸如视频之类的冗长下载,请使用Windows.Networking.BackgroundTransfer.BackgroundDownloader。如果您需要在下载完成后处理文件,则可以将该完成操作用作后台任务的触发。

请参阅提供的文档链接以获取概述和操作方法。 https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/BackgroundTransfer

有完整的示例

答案 1 :(得分:0)

所以我决定在这里写下自己的答案,因为我不确定是否有人会解决这个问题。我怀疑的一件事是我最近将C#语言更新为v7.3,因为VS 2017在编写一些代码时是这样说的。也许与此有关,但是到目前为止,我的解决方案在最小化状态下工作。

我还想在此声明,我首先实施BackgroundTask来解决这个问题,使用ApplicationTrigger在需要时触发该过程,但说实话,这是一种hack。看一下代码:

public static async Task<string> GetBackgroundTaskReturnValue(string apiRequestUrl)
{
        StaticItemsHelper.IsBackgroundPlaylistTaskRunning = true;
        if (StaticItemsHelper.IsBackgroundPlaylistTaskRunning)
        {
            for (int seconds = 0; seconds < 20;)
            {
                if (!StaticItemsHelper.IsBackgroundPlaylistTaskRunning)
                {
                    break;
                }
                else
                {
                    Task.Delay(1000).Wait();
                }
            }
        }
        var request = BackgroundTaskHelper.BackgroundPlaylistTrigger.RequestAsync().GetResults();
        if (request == Windows.ApplicationModel.Background.ApplicationTriggerResult.Allowed)
        {
            SettingsHelper.localSettings.Values[SettingsHelper.BackgroundPlaylistPlaybackURLKey] = apiRequestUrl;
            SettingsHelper.localSettings.Values[SettingsHelper.BackgroundPlaylistPlaybackTokenKey] = StaticItemsHelper.CurrentUserAccessToken;
            if (SettingsHelper.tempFolder.TryGetItemAsync(SettingsHelper.BackgroundPlaylistPlaybackReturnKey).GetResults() is StorageFile file)
            {
                await file.DeleteAsync();
            }
            for (int seconds = 0; seconds < 30;)
            {
                if (SettingsHelper.tempFolder.TryGetItemAsync(SettingsHelper.BackgroundPlaylistPlaybackReturnKey).GetResults() is StorageFile _rfile)
                {
                    var _returnVal = FileIO.ReadTextAsync(_rfile).GetResults();
                    if (!string.IsNullOrEmpty(_returnVal.ToString()))
                    {
                        await _rfile.DeleteAsync();
                        SettingsHelper.localSettings.Values.Remove(SettingsHelper.BackgroundPlaylistPlaybackTokenKey);
                        SettingsHelper.localSettings.Values.Remove(SettingsHelper.BackgroundPlaylistPlaybackURLKey);
                        StaticItemsHelper.IsBackgroundPlaylistTaskRunning = false;
                        return _returnVal;
                    }
                }
                Task.Delay(2000).Wait();
                seconds += 2;
            }
        }
        else if (request == Windows.ApplicationModel.Background.ApplicationTriggerResult.CurrentlyRunning)
        {
            for (int seconds = 0; seconds < 30;)
            {
                Task.Delay(2000).Wait();
                seconds += 2;
                request = BackgroundTaskHelper.BackgroundPlaylistTrigger.RequestAsync().GetResults();
                if (request == Windows.ApplicationModel.Background.ApplicationTriggerResult.Allowed)
                {
                    return GetBackgroundTaskReturnValue(apiRequestUrl).Result;
                }
            }
        }
        if (SettingsHelper.tempFolder.TryGetItemAsync(SettingsHelper.BackgroundPlaylistPlaybackReturnKey).GetResults() is StorageFile _file)
        {
            await _file.DeleteAsync();
        }
        SettingsHelper.localSettings.Values.Remove(SettingsHelper.BackgroundPlaylistPlaybackTokenKey);
        SettingsHelper.localSettings.Values.Remove(SettingsHelper.BackgroundPlaylistPlaybackURLKey);
        StaticItemsHelper.IsBackgroundPlaylistTaskRunning = false;
        return "{ \"error\": {\"code\": \"NetworkError\", \"message\": \"Server returned nothing.\"} }";
}

实际解决方案: 但是后来它也没有按我预期的那样工作,所以我决定删除它,而是使用以下代码。 (将此与问题进行比较)

public static async Task<string> GetResponseDataFromAPI(string apiRequestUrl, CancellationTokenSource cts = default)
{
        cts = cts ?? new CancellationTokenSource(TimeSpan.FromSeconds(20));
        try
        {
            if (StaticItemsHelper.IsAppInBackground)
            {
                //return await ViewHelper.GetBackgroundTaskReturnValue(apiRequestUrl);
                var responseData = AuthRequestHelper.globalHttpClient.GetAsync(apiRequestUrl, cts.Token).Result;
                var result = responseData.Content.ReadAsStringAsync().Result;
                return result;
            }
            else
            {
                var responseData = await AuthRequestHelper.globalHttpClient.GetAsync(apiRequestUrl, cts.Token);
                var result = await responseData.Content.ReadAsStringAsync();
                return result;
            }
        }
        catch (Exception ex)
        {
            INotifyHelper.iNotifyObject.IsDataLoading = false;
            // show error
            return "{ \"error\": {\"code\": " + $"\"{ex.HResult}\", \"message\": \"{ex.Message}\"" + "} }";
        }
}

希望这对其他人有帮助。