iOS后台线程在UI空闲时变慢

11

首先需要一些背景信息

我有一个Xamarin应用程序,基本上从远程服务器流式传输视频。我有一个后台线程像这样循环(伪代码):

private void UpdateMethod()
{
    while (running)
    {
        bool success = WaitForUpdate();

        if (!success)
        {
            break;
        }

        Update update = GetUpdate();
        SendUpdateToConcurentQueue(update);
    }

    Disconnect();
}

我这样启动后台线程:

Thread thread = new Thread(UpdateMethod);
thread.IsBackground = true;
thread.Start();

问题

当我开始流播放时,一切都很完美。只有在与设备无交互约10秒钟后,它变得非常缓慢。我输出了后台线程的更新数量,它们似乎要慢得多。我通常每个更新处理2-6次更新(60fps)。当速度非常慢时,我每6个更新周期才会得到1次更新。

有一件让我困惑的事情:当我下拉iOS顶部栏菜单时,更新率就会上升,流播放突然回到正常速度。更新速率会提高约10秒钟,然后又会像疯子一样滞后。

我的尝试

我尝试启动一个仅执行此操作的Dispatch队列,如下所示:

DispatchQueue queue = new DispatchQueue("updateQueue");
queue.DispatchAsync(this.UpdateProcess);

这似乎完全没有帮助。

我还尝试像这样更改我的更新线程中的QualityOfService属性:

NSThread.Current.QualityOfService = NSQualityOfService.UserInitiated

也不行!我觉得iOS出于某种原因降低了我的线程优先级。如果我在UpdateMethod方法中设置断点,当应用程序不会出现延迟时,它会被命中。但当出现延迟时,断点不会被命中。现在这真的让我感到困惑,因为代码仍在运行!我仍然收到更新,只是速度慢了很多...

编辑:我使用Instruments进行了测试,并发现网络正在受到限制...正在进行调查,但如果有人知道iOS上任何类型的网络限制,请让我知道。

1个回答

4
尝试将IdleTimerDisabled设置为true,我们在iOS游戏中经常这样做,以防止iOS使我们的游戏处于空闲状态。
注意:只有在用户由于观看回放、级别变化多媒体过渡等原因不触摸屏幕时,我们才以礼貌的方式这样做。
注意:确保在不需要它时(当您的应用程序进入后台等情况),重置空闲时间,因为这会导致电池耗尽并让用户对您的应用程序感到失望,甚至可能导致Apple Store拒绝
苹果:App Idle Timer info Xamarin: UIKit.UIApplication.IdleTimerDisabled Property 这个属性的默认值是NO。当大多数应用程序在短时间内没有触摸作为用户输入时,系统会将设备置于“睡眠”状态,屏幕变暗。这是为了节省电力。然而,除了加速度计之外没有用户输入的应用程序(例如游戏),可以通过将此属性设置为YES来禁用“空闲计时器”,以避免系统睡眠。 | 重要提示
只有地图应用程序、游戏或需要在用户交互最少时继续显示内容的程序才应禁用空闲计时器。您应该仅在必要时设置此属性,并确保在不再需要时将其重置为NO。大多数应用程序应该让系统在空闲计时器到期时关闭屏幕。这包括音频应用程序。通过适当使用音频会话服务,播放和录制在屏幕关闭时可以无间断进行。

我相当确定我也试过这个...但我会再试一次。不过似乎这是针对屏幕变暗的,而不仅仅是在10秒后才发生的。 - Philippe Paré
我刚刚测试了一下... 仍然有延迟 :( - Philippe Paré
任何物理设备,无线网络。 - Philippe Paré
@PhilippeParé 你确定这只是iOS相关问题吗?你的逻辑在桌面或其他设备上运行良好吗?此外,延迟可能存在于后台线程逻辑、队列或数据中,导致算法性能不佳,这与iOS无关。 - Akash Kava
@AkashKava 是的,我在安卓版本中使用了相同的代码,而且它可以顺利运行。 - Philippe Paré
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接