2 回答
TA贡献1794条经验 获得超8个赞
的BackgroundTransfer类专门在后台下载数据设计,即使应用程序已被暂停或关闭。
HttpClient 更适合快速完成的非常短的下载。对于像视频这样的冗长下载,请使用Windows.Networking.BackgroundTransfer.BackgroundDownloader。如果您需要在下载完成时处理文件,您可以使用该完成作为后台任务的触发器。
有关概述和操作方法,请参阅提供的文档链接。https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/BackgroundTransfer 上有一个完整的示例
TA贡献1799条经验 获得超8个赞
所以我决定在这里写下我自己的答案,因为我不确定其他人是否会解决这个问题。我怀疑的一件事是我最近将 C# 语言更新到了 v7.3,因为 VS 2017 在编写一些代码时是这样说的。也许问题与此有关,但到目前为止我的解决方案在最小化状态下工作。
我还想在此声明,我BackgroundTask首先实施以ApplicationTrigger在需要时触发该过程来克服这个问题,但老实说这是一种黑客攻击。看一下代码:
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}\"" + "} }";
}
}
希望这对其他人有所帮助。
- 2 回答
- 0 关注
- 217 浏览
添加回答
举报