1
votes

I'm working on a small .NET Standard 2.0 logging library, and I'm having trouble finding a way to reliably get the memory used by the current process across all platforms, especially on UWP.

Right now I'm using this code (.NET Standard 2.0):

long memory = Process.GetCurrentProcess().PrivateMemorySize64;

Which works fine, but throws a nice PlatformNotSupportedException exception on UWP (actually, that's only in DEBUG mode, while in RELEASE is directly throws a TypeLoadException plus a bunch of other P/Invoke exceptions for some reason).

The problem here is that that API is obviously not supported on UWP, where I should use:

long memory = (long)MemoryManager.AppMemoryUsage;

The problem is that the MemoryManager is a UWP-only API, and it is not present in .NET Standard 2.0. Now, the first workaround that comes to mind is to expose a setting in the library to let the user manually set a custom Func<long> delegate that retrieves the current memory usage, so that if it knows the default method won't work on the current platform, it'll be possible to override it.

This seems like a bad trick though, and I'd like to keep everything self-contained withing the library instead. So my question is:

Is there a way to reliably retrieve the current process/app usage across any platform that supports .NET Standard 2.0 libraries?

Thanks!

2

2 Answers

1
votes

Maybe a little dirty, but the following could work (may add some better error handling and such):

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));
    }
}

I use reflection to get around the fact that MemoryManager is not available for .NET Standard at compile time, but for the UWP runtime. This way the same assembly would work for both runtimes.
But in general I would prefer a way which generates a fitting assembly per runtime like suggested by Martin.

0
votes

I think you could use the same trick previously used for Portable Class Libraries - Bait and Switch. It is still compatible with .NET Standard 2.0. This way you can create a specific implementation for UWP and fall back to the standard implementation otherwise.