猿问

HttpClient 未在最小化的 UWP 应用程序中执行 GetAsync

我正在做一个播放几个视频的项目。为了能够播放这些视频,我需要在应用程序通过HttpClientfrom请求时获取它们的数据System.Net.Http。一切正常,当应用程序处于前台时,UWP 应用程序会从 Internet 下载所需的信息。


一旦应用程序离开前台并被用户最小化HttpClient,无论是来自命名空间System.Net.Http还是Windows.Web.Http命名空间,都不起作用。我什至试图在那里设置一个断点,一旦我继续前进HttpClient就不会响应该await client.GetAsync()方法并停留在那里而不返回任何结果,除非您再次激活该应用程序然后它返回任何值。我无法使用,BackgroundTasks因为他们需要,Triggers但我需要按需访问数据。


我也读过这篇文章,描述了请求,ExtendedExecutionState但结果还是一样。当应用程序收到播放项目列表的请求时,我会请求此状态。即使在获得结果为 之后Allowed,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是:


public static async void RequestBackgroundExtendedExecution()

{

    using (var session = new ExtendedExecutionSession())

    {

        session.Reason = ExtendedExecutionReason.Unspecified;

        session.Description = "Background Playlist Playback";

        session.Revoked += Session_Revoked;

        if (await session.RequestExtensionAsync() is ExtendedExecutionResult result)

        {

            if (result == ExtendedExecutionResult.Denied)

            {

                // show user that background playlist playback will not be possible

            }

        }

    }

}

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


人到中年有点甜
浏览 218回答 2
2回答

幕布斯7119047

的BackgroundTransfer类专门在后台下载数据设计,即使应用程序已被暂停或关闭。HttpClient 更适合快速完成的非常短的下载。对于像视频这样的冗长下载,请使用Windows.Networking.BackgroundTransfer.BackgroundDownloader。如果您需要在下载完成时处理文件,您可以使用该完成作为后台任务的触发器。有关概述和操作方法,请参阅提供的文档链接。https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/BackgroundTransfer 上有一个完整的示例

守着星空守着你

所以我决定在这里写下我自己的答案,因为我不确定其他人是否会解决这个问题。我怀疑的一件事是我最近将 C# 语言更新到了 v7.3,因为 VS 2017 在编写一些代码时是这样说的。也许问题与此有关,但到目前为止我的解决方案在最小化状态下工作。我还想在此声明,我BackgroundTask首先实施以ApplicationTrigger在需要时触发该过程来克服这个问题,但老实说这是一种黑客攻击。看一下代码:public static async Task<string> GetBackgroundTaskReturnValue(string apiRequestUrl){&nbsp; &nbsp; &nbsp; &nbsp; StaticItemsHelper.IsBackgroundPlaylistTaskRunning = true;&nbsp; &nbsp; &nbsp; &nbsp; if (StaticItemsHelper.IsBackgroundPlaylistTaskRunning)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int seconds = 0; seconds < 20;)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!StaticItemsHelper.IsBackgroundPlaylistTaskRunning)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Task.Delay(1000).Wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; var request = BackgroundTaskHelper.BackgroundPlaylistTrigger.RequestAsync().GetResults();&nbsp; &nbsp; &nbsp; &nbsp; if (request == Windows.ApplicationModel.Background.ApplicationTriggerResult.Allowed)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SettingsHelper.localSettings.Values[SettingsHelper.BackgroundPlaylistPlaybackURLKey] = apiRequestUrl;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SettingsHelper.localSettings.Values[SettingsHelper.BackgroundPlaylistPlaybackTokenKey] = StaticItemsHelper.CurrentUserAccessToken;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (SettingsHelper.tempFolder.TryGetItemAsync(SettingsHelper.BackgroundPlaylistPlaybackReturnKey).GetResults() is StorageFile file)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await file.DeleteAsync();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int seconds = 0; seconds < 30;)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (SettingsHelper.tempFolder.TryGetItemAsync(SettingsHelper.BackgroundPlaylistPlaybackReturnKey).GetResults() is StorageFile _rfile)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var _returnVal = FileIO.ReadTextAsync(_rfile).GetResults();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!string.IsNullOrEmpty(_returnVal.ToString()))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await _rfile.DeleteAsync();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SettingsHelper.localSettings.Values.Remove(SettingsHelper.BackgroundPlaylistPlaybackTokenKey);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SettingsHelper.localSettings.Values.Remove(SettingsHelper.BackgroundPlaylistPlaybackURLKey);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StaticItemsHelper.IsBackgroundPlaylistTaskRunning = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return _returnVal;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Task.Delay(2000).Wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; seconds += 2;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; else if (request == Windows.ApplicationModel.Background.ApplicationTriggerResult.CurrentlyRunning)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int seconds = 0; seconds < 30;)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Task.Delay(2000).Wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; seconds += 2;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; request = BackgroundTaskHelper.BackgroundPlaylistTrigger.RequestAsync().GetResults();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (request == Windows.ApplicationModel.Background.ApplicationTriggerResult.Allowed)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return GetBackgroundTaskReturnValue(apiRequestUrl).Result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (SettingsHelper.tempFolder.TryGetItemAsync(SettingsHelper.BackgroundPlaylistPlaybackReturnKey).GetResults() is StorageFile _file)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; await _file.DeleteAsync();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; SettingsHelper.localSettings.Values.Remove(SettingsHelper.BackgroundPlaylistPlaybackTokenKey);&nbsp; &nbsp; &nbsp; &nbsp; SettingsHelper.localSettings.Values.Remove(SettingsHelper.BackgroundPlaylistPlaybackURLKey);&nbsp; &nbsp; &nbsp; &nbsp; StaticItemsHelper.IsBackgroundPlaylistTaskRunning = false;&nbsp; &nbsp; &nbsp; &nbsp; return "{ \"error\": {\"code\": \"NetworkError\", \"message\": \"Server returned nothing.\"} }";}实际解决方案: 但是它也没有按我预期的那样工作,所以我决定放弃它并使用以下代码代替。(将此与问题进行比较)public static async Task<string> GetResponseDataFromAPI(string apiRequestUrl, CancellationTokenSource cts = default){&nbsp; &nbsp; &nbsp; &nbsp; cts = cts ?? new CancellationTokenSource(TimeSpan.FromSeconds(20));&nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (StaticItemsHelper.IsAppInBackground)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //return await ViewHelper.GetBackgroundTaskReturnValue(apiRequestUrl);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var responseData = AuthRequestHelper.globalHttpClient.GetAsync(apiRequestUrl, cts.Token).Result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var result = responseData.Content.ReadAsStringAsync().Result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var responseData = await AuthRequestHelper.globalHttpClient.GetAsync(apiRequestUrl, cts.Token);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var result = await responseData.Content.ReadAsStringAsync();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; catch (Exception ex)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INotifyHelper.iNotifyObject.IsDataLoading = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // show error&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "{ \"error\": {\"code\": " + $"\"{ex.HResult}\", \"message\": \"{ex.Message}\"" + "} }";&nbsp; &nbsp; &nbsp; &nbsp; }}希望这对其他人有所帮助。
随时随地看视频慕课网APP
我要回答