macos - 为什么我的 MacOS 应用程序在打瞌睡,尽管我指示它不要打瞌睡

标签 macos xamarin.mac

虽然这是在 Xamarin.Mac 项目中发生的,但我认为问题更多地与 MacOS 有关,因为迹象是 App Nap 的迹象。

在我的 AppDelegate.cs 文件中,我有以下内容:

public override void DidFinishLaunching(NSNotification notification)
{
    _activity = NSProcessInfo.ProcessInfo.BeginActivity(
                    NSActivityOptions.Background |
                    NSActivityOptions.LatencyCritical,
                    "You charge $3,500AUD for this laptop and yet " +
                    "can't provide enough resources for a smooth " +
                    "operation of this app in the background? " +
                    "Eat a d#@k Apple."
                );
    // ...

我使用每 ~1 秒运行一次的以下命令测试了上述内容:

var now = DateTime.Now;
var now_str = now.ToString("HH:mm:ss.fff");
Debug.WriteLine(now_str);
var idle_time = now - _prevTime;
if (idle_time.TotalMilliseconds > 1200)
{
    Debug.WriteLine("FFSakes Apple!");
}
_prevTime = now;
await Task.Delay(1000); // yes yes, I know timers aren't precise, hence why I said '~'1s.

经过几个小时的努力,我决定运行该应用程序,将其置于后台,然后去小睡一会儿。事实证明,我的应用程序也是如此。在我将其打开的 1.5 小时内,它执行了以下操作:

19:23:29.040
19:23:30.041
19:56:07.176
FFSakes Apple!
19:56:08.196
19:56:09.196
...

延迟超过半小时!

问题 1:为什么?
问题 2:我该如何解决这个问题?

重现: https://github.com/FunkyLambda/AppNapRepro

最佳答案

您没有指示您的应用避免小睡。正确选项是:

userInitiated :

Flag to indicate the app is performing a user-requested action.

userInitiatedAllowingIdleSystemSleep :

Flag to indicate the app is performing a user-requested action, but that the system can sleep on idle.

Extend App Nap文档:

If an app isn’t performing user-initiated work such as updating content on screen, playing music, or downloading a file, the system may put the app in App Nap.

您的应用正在使用背景:

Flag to indicate the app has initiated some kind of work, but not as the direct result of user request.

再次查看文档...

App Nap conserves battery life by regulating the app’s CPU usage and by reducing the frequency with which its timers are fired.

...这就是您可能看到的结果。


即使我指定 LatencyCriticial,系统仍然可以让我的应用休眠,因为我只指定了 Background

是的。你可以简单地自己检查一下。运行您的应用程序,打开“事件监视器”,右键单击表格标题行并添加“应用程序午睡”和“防止 sleep ”列。让您的应用运行一段时间,几分钟就足够了,然后检查这些列值。

本质上,App Nap 的条件是否简化为:如果不是用户启动且不更新 View ,则可能会使其休眠?

不,请检查文档。

Generally, an app is a candidate for App Nap if:

  • It isn’t the foreground app
  • It hasn’t recently updated content in the visible portion of a window
  • It isn’t audible
  • It hasn’t taken any IOKit power management or NSProcessInfo assertions
  • It isn’t using OpenGL

When the above conditions are met, OS X may put the app in App Nap.

还要注意差异 - 可能放置 != 将放置,...其背后的启发式方法,其行为在不同的 macOS 版本上可能略有不同。

我的应用程序在打开时会运行多个进程,这些进程都不是用户启动的,但对于用户不间断地运行很重要,因此,如果我保留它的配置,但使其更新 View 作为一部分周期性定时器,应该免于App Nap?

我不会过多关注用户发起的词。 userInitiated 文档说:

Flag to indicate the app is performing a user-requested action.

它基本上意味着用户正在等待的任何事情。如果您正在更新 UI,例如,基于用户不是通过某个按钮启动的某些任务的输出,它仍然可以是用户请求的操作(用户启动您的应用程序以获取一些结果,...) .

更多信息

我不知道你的应用程序应该做什么 -> 很难推荐任何实现它的方法。但我强烈建议观看:

阅读:

即使这些演示文稿很旧,它也是一个存档文档,...它仍然有效并且包含许多有用的信息。

关于macos - 为什么我的 MacOS 应用程序在打瞌睡,尽管我指示它不要打瞌睡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61774220/

相关文章:

Mac 上的 Xamarin 出现错误 :/usr/bin/mono: No such file or directory

macos - 从Time Machine胶囊进行异地备份

macos - Mac电脑有免费的shell服务吗?

linux - 查找相似的文本文件

Xamarin iOS 安装失败

macos - Xamarin 中的 MDItem 类

c++ - 如何从现有的 git cmake 项目创建 Xcode 项目?

macos - HSLab:空音频设备

c# - WKWebView 使用 LoadFileUrl 加载本地内容

json - 执行 WebAPI 2 JSON Post 时未找到 HttpRequestBase.GetBufferedInputStream