当UI处于空闲状态时,iOS后台线程会变慢

时间:2016-05-05 18:24:08

标签: c# ios multithreading xamarin xamarin.ios

首先是一些背景

我有一个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)。当它超级慢时,我得到1个6更新周期。

有一件事让我感到困惑:当我下拉iOS顶部栏菜单时,更新会重新启动,流会突然恢复正常速度。更新率上升了大约10秒,然后又像疯了一样回落。

我尝试了什么

我尝试启动一个Dispatch队列,只有这个,就像这样:

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

它似乎没有任何帮助。

我还尝试在更新线程中更改QualityOfService属性,如下所示:

NSThread.Current.QualityOfService = NSQualityOfService.UserInitiated

也不起作用!在我看来iOS由于某种原因降低了我的线程的优先级。如果我在我的UpdateMethod方法中放置一个断点,那么当应用程序没有滞后时它就会被击中。但是当出现滞后时,断点就不会受到打击。现在这真让我困惑,因为代码仍在运行!我仍然收到更新,这只是慢一点......

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

1 个答案:

答案 0 :(得分:4)

尝试将IdleTimerDisabled设置为true,我们会一直在iOS游戏中执行此操作,以防止iOS闲置我们的游戏。

注意:我们只在用户因为观看重播,级别更改多媒体段等而未触摸屏幕时才在polite way中执行此操作...

注意:确保在不需要时重置闲置(当你的应用程序在后台运行时等等),例如杀死电池并让用户对你的应用程序感到沮丧杀手: Apple Store拒绝

Apple:App Idle Timer info

Xamarin:UIKit.UIApplication.IdleTimerDisabled Property

  

此属性的默认值为NO。当大多数应用程序在短时间内没有触摸作为用户输入时,系统会将设备置于屏幕变暗的“睡眠”状态。这样做是为了节省电量。但是,没有用户输入的应用程序除了加速计 - 游戏,例如 - 可以,通过将此属性设置为YES,禁用“空闲计时器”以避免系统睡眠。

     

|重要

     

您应该仅在必要时设置此属性,并且当需要不再存在时,应确保将其重置为NO。当空闲计时器过去时,大多数应用程序应让系统关闭屏幕。这包括音频应用。通过适当使用音频会话服务,当屏幕关闭时,播放和录制不会中断。 应该禁用空闲计时器的唯一应用是映射应用,游戏或程序,以便在用户互动最少时应用需要继续显示内容。