【发布时间】:2021-01-27 23:13:44
【问题描述】:
我有一个应用程序 (App1),它使用 WKWebView 作为 UI 的很大一部分。有一种情况是,从WKWebView 向后端服务器发送 HTTP PUT 请求以保存一些数据。要完成此保存操作,服务器将需要通过另一个应用程序 (App2) 的批准。用户通常会切换到 App2 进行批准,然后切换回 App1 以查看保存结果。问题是当 App1 进入后台时,它可能导致对保存请求的响应被取消,即使在后端服务器上保存完全成功。实际上没有记录任何错误,但我相当肯定它正在发生,因为当应用程序在后台运行后暂停时,iOS 正在终止连接。我的想法基于this discussion。
由于批准在 App2 上保存所需的时间并没有那么长,我想我可以尝试延长 App1 的后台时间,并且在我测试过的时间内它似乎可以工作。
但是,我想知道这是否真的是最好的策略,如果是,对我的代码是否有任何建议(例如,我是否应该将 BeginBackgroundTask 移动到 Task.Run 内):
我以这些microsoft docs 为例。
public override async void DidEnterBackground(UIApplication application)
{
ExtendBackgroundTime(application);
}
private nint? webViewBgTaskId = null;
private CancellationTokenSource webViewBgTaskTokenSrc = null;
private void ExtendBackgroundTime(UIApplication application)
{
// cancel the previous background task that was created in this function
webViewBgTaskTokenSrc?.Cancel();
webViewBgTaskTokenSrc = null;
if (webViewBgTaskId.HasValue)
{
application.EndBackgroundTask(webViewBgTaskId.Value);
webViewBgTaskId = null;
}
var cts = new CancellationTokenSource();
nint taskId = default;
taskId = application.BeginBackgroundTask(() =>
{
cts.Cancel();
webViewBgTaskTokenSrc = null;
application.EndBackgroundTask(taskId);
webViewBgTaskId = null;
});
_ = Task.Run(async () =>
{
// For now, this is just set to 5 minutes, but in my experience,
// the background task will never be allowed to continue for that long.
// It's usually only about 30 seconds as of iOS 13.
// But this at least gives it some finite upper bound.
await Task.Delay(TimeSpan.FromMinutes(5), cts.Token);
application.EndBackgroundTask(taskId);
webViewBgTaskId = null;
}, cts.Token);
webViewBgTaskTokenSrc = cts;
webViewBgTaskId = taskId;
}
【问题讨论】:
-
嗨,你看看this official sample吗?
-
@JuniorJiang-MSFT 谢谢你的链接。我看了看,大部分都是有道理的。在调用
EndBackgroundTask之前它没有取消任务有什么原因吗?对我来说这似乎是合乎逻辑的,因为文档说要调用EndBackgroundTask来表明该任务的后台处理已经结束。 -
你好,为什么它会在调用
EndBackgroundTask之前取消任务?如果你调用EndBackgroundTask,那么它会取消任务。 -
@JuniorJiang-MSFT 我说的是这里创建的任务:
Task.Factory.StartNew(() => FinishLongRunningTask(taskID));。 -
好吧,我已经更新了一个答案来解释这一点。
标签: c# ios xamarin xamarin.ios task-parallel-library