private void SetWorkingSetLimitsCore(IntPtr? newMin, IntPtr? newMax, out IntPtr resultingMin, out IntPtr resultingMax)
{
SafeProcessHandle handle = null;
try
{
handle = GetProcessHandle(Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION | Interop.Advapi32.ProcessOptions.PROCESS_SET_QUOTA);
IntPtr min, max;
int ignoredFlags;
if (!Interop.Kernel32.GetProcessWorkingSetSizeEx(handle, out min, out max, out ignoredFlags))
{
throw new Win32Exception();
}
if (newMin.HasValue)
{
min = newMin.Value;
}
if (newMax.HasValue)
{
max = newMax.Value;
}
if ((long)min > (long)max)
{
if (newMin != null)
{
throw new ArgumentException(SR.BadMinWorkset);
}
else
{
throw new ArgumentException(SR.BadMaxWorkset);
}
}
// We use SetProcessWorkingSetSizeEx which gives an option to follow
// the max and min value even in low-memory and abundant-memory situations.
// However, we do not use these flags to emulate the existing behavior
if (!Interop.Kernel32.SetProcessWorkingSetSizeEx(handle, min, max, 0))
{
throw new Win32Exception();
}
// The value may be rounded/changed by the OS, so go get it
if (!Interop.Kernel32.GetProcessWorkingSetSizeEx(handle, out min, out max, out ignoredFlags))
{
throw new Win32Exception();
}
resultingMin = min;
resultingMax = max;
}
finally
{
ReleaseProcessHandle(handle);
}
}