代码之家  ›  专栏  ›  技术社区  ›  Sergio0694

如何从两者获取进程内存。NET标准2.0和UWP?

  •  1
  • Sergio0694  · 技术社区  · 7 年前

    我正在做一个小的。净标准2.0 logging library ,我很难找到一种方法来可靠地获取当前进程在所有平台上使用的内存,尤其是在UWP上。

    现在我正在使用以下代码(.NET Standard 2.0):

    long memory = Process.GetCurrentProcess().PrivateMemorySize64;
    

    效果很好, 但是 抛出一个漂亮的 PlatformNotSupportedException UWP上的异常(实际上,这只是在调试模式下,而在发行版中是直接抛出 TypeLoadException 再加上一些其他P/Invoke异常)。

    这里的问题是,UWP显然不支持该API,我应该使用:

    long memory = (long)MemoryManager.AppMemoryUsage;
    

    问题是 MemoryManager 是一个仅限UWP的API,它不存在于中。净标准2.0。现在,想到的第一个解决方法是在库中公开一个设置,让用户手动设置自定义 Func<long> 委托检索当前内存使用情况,以便如果它知道默认方法在当前平台上不起作用,则可以重写它。

    这似乎是一个糟糕的把戏,我想在图书馆里保持一切自给自足。所以我的问题是:

    是否有一种方法可以跨任何支持的平台可靠地检索当前进程/应用程序的使用情况。NET标准2.0库?

    谢谢

    2 回复  |  直到 7 年前
        1
  •  1
  •   Christoph Fink Nathan    7 年前

    大概 有点脏,但以下可能会起作用(可能会添加一些更好的错误处理等):

    public static long GetProcessMemory()
    {
        try
        {
            return Process.GetCurrentProcess().PrivateMemorySize64;
        }
        catch
        {           
            var type = Type.GetType("Windows.System.MemoryManager, Windows, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime");
            return Convert.ToInt64(type.GetProperty("AppMemoryUsage", BindingFlags.Public | BindingFlags.Static).GetValue(null, null));
        }
    }
    

    我用反思来回避这样一个事实 MemoryManager 不可用于。NET标准,但适用于UWP运行时。这样,相同的程序集将同时适用于两个运行时。
    但总的来说,我更喜欢像Martin建议的那样,在每个运行时生成装配程序集。

        2
  •  0
  •   Martin Zikmund    7 年前

    我认为您可以使用之前用于可移植类库的相同技巧- Bait and Switch . 它仍然是 compatible with .NET Standard 2.0 . 通过这种方式,您可以为UWP创建一个特定的实现,否则就返回到标准实现。