将后台安全任务与 async/await 一起使用时的正确实现

本文关键字:实现 一起 await 安全 后台 任务 async | 更新日期: 2023-09-27 18:35:04

如果用户按下主页按钮或正在打开应用程序切换器或正在接收来电,则当前正在运行的任务(Web 请求)应在后台完成。我没有为此使用NSURLSession,因为我现在不想更改当前的基础类。因此,我想使用后台安全任务。

我试过这个:

public async Task retrieveCarList(){
    backgroundTaskID = UIApplication.SharedApplication.BeginBackgroundTask (() => {
        if(backgroundTaskID != 0){
            UIApplication.SharedApplication.EndBackgroundTask(backgroundTaskID);
            backgroundTaskID = 0;
        }
    });
    List<Car> carList = await manager.GetCarList();
    if(carList != null) {
        this.list = carList;
    } else {
        new UIAlertView("Error occurred", "", null, "OK", null).Show();
    }
    if(backgroundTaskID != 0){
        UIApplication.SharedApplication.EndBackgroundTask(backgroundTaskID);
        backgroundTaskID = 0;
    }
}

这似乎有效,但我必须对其进行更多测试。

问题

  1. 我可以在应用程序的各个位置使用 BeginBackgroundTask/EndBackgroundTask吗?大多数示例仅在DidEnterBackground中使用它...

  2. 系统如何知道此后台线程的开始和结束位置?

  3. BeginBackgroundTaskEndBackgroundTask之间的代码是否甚至使用与UI相关的东西?

  4. 这是博客文章之后的正确实现吗iOS中的多任务处理:单点触控方式–第一部分:按下主屏幕按钮但async/await

编辑 1:

现在我尝试与Console.WriteLine合作.似乎执行了await表达式,但之后的代码仅在用户再次打开应用程序时才执行。我担心的是,只有当用户回到应用程序时,才会执行EndBackgroundTask。因此,如果不调用EndBackgroundTask该应用程序可能会被杀死。

另一方面,如果我不使用后台安全任务,如果按下主页按钮,应用程序将不再在后台执行 Web 请求。所以它有点工作...

如何将所有代码行放入await表达式中?那么所有代码都应该被执行,或者?

编辑 2:

await表达式放在System.Action之间会导致应用崩溃,并且不会显示任何错误。我还尝试在 retrieveCarList() 中使用 BeginBackgroundTask,并在等待的 GetCarList() 中使用EndBackgroundTask,但代码只有在我回到应用程序中时才执行。 此外,我试图将我的await包装在另一个Task.Run中,但这带来了问题,因为我正在访问与 UI 相关的东西,而这种结构是不可能的。我的第一次尝试似乎仍然是最好的,但它有上述缺点。如果有人有更好的实现,请发布它。

将后台安全任务与 async/await 一起使用时的正确实现

解决方案:

1.) Xamarin 文档说我可以在任何地方使用这种模式。这在苹果文档中也有说明。

可以在应用执行过程中的任何时候调用此方法。

2.) 迪米特里斯·塔夫利科斯州

它是在 BeginBackgroundTask 调用之后,您的后台时间开始。

3.) 根据 Bryan Costanich 的 Development C# Apps for iPhone

和 iPad: iOS Apps Development by Bryan Costanich,UI 线程似乎已暂停。

4.)我的方法似乎工作正常。现在我把Console.WriteLine放在EndBackgroundTask之前,它被称为它应该的!执行 BeginBackgroundTaskEndBackgroundTask 之间的所有内容。只有backgroundTaskID不会被清除,但其他实现也不会这样做。