【问题标题】:Reduce CPU usage asp net mvc减少 CPU 使用率 asp net mvc
【发布时间】:2019-08-08 08:12:23
【问题描述】:

我希望我的进程不会超过 70% 的 CPU 使用率。我在这里找到了解决方案: How can I programmatically limit my program's CPU usage to below 70%? 。这是我试图从该链接使用的类:

public class ProcessManager
    {
        [Flags]
        public enum ThreadAccess : int
        {
            TERMINATE = (0x0001),
            SUSPEND_RESUME = (0x0002),
            GET_CONTEXT = (0x0008),
            SET_CONTEXT = (0x0010),
            SET_INFORMATION = (0x0020),
            QUERY_INFORMATION = (0x0040),
            SET_THREAD_TOKEN = (0x0080),
            IMPERSONATE = (0x0100),
            DIRECT_IMPERSONATION = (0x0200)
        }

        [DllImport("kernel32.dll")]
        static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);

        [DllImport("kernel32.dll")]
        static extern uint SuspendThread(IntPtr hThread);

        [DllImport("kernel32.dll")]
        static extern int ResumeThread(IntPtr hThread);

        [DllImport("kernel32.dll")]
        static extern int CloseHandle(IntPtr hThread);
        public static void ThrottleProcess(int processId, double limit)
        {
            var process = Process.GetProcessById(processId);
            var processName = process.ProcessName;

            var p = new PerformanceCounter("Process", "% Processor Time", processName);

            while (true)
            {
                var interval = 100;
                Thread.Sleep(interval);

                var currentUsage = p.NextValue() / Environment.ProcessorCount;

                if (currentUsage < limit) continue; // Infinant loop ?

                var suspensionTime = (currentUsage-limit) / currentUsage * interval;
                SuspendProcess(processId);
                Thread.Sleep((int)suspensionTime);
                ResumeProcess(processId);
            }
        }

        private static void SuspendProcess(int pid)
        {
            var process = Process.GetProcessById(pid);

            if (process.ProcessName == string.Empty)
                return;

            foreach (ProcessThread pT in process.Threads)
            {
                IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);

                if (pOpenThread == IntPtr.Zero)
                {
                    continue;
                }

                SuspendThread(pOpenThread);

                CloseHandle(pOpenThread);
            }
        }

        private static void ResumeProcess(int pid)
        {
            var process = Process.GetProcessById(pid);

            if (process.ProcessName == string.Empty)
                return;

            foreach (ProcessThread pT in process.Threads)
            {
                IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);

                if (pOpenThread == IntPtr.Zero)
                {
                    continue;
                }

                var suspendCount = 0;

                do
                {
                    suspendCount = ResumeThread(pOpenThread);
                } while (suspendCount > 0);

                CloseHandle(pOpenThread);
            }
        }
    }

这段代码的作者在他的帖子下留下了评论说,使用 ThrottleProcess after Process.Start()。我做到了,但似乎在 Process 启动之后,它就进入了 ThrottleProcess 和 get stucks inside While 循环。而且我不知道该怎么办,也许它应该异步运行方法?就像 Process 应该独立于 Throttle 运行不是吗? 这是我的 Process 方法:

private string startProcess(string fileName, string args)
        {
            // Create Process manager
            var ProcessManager = new ProcessManager();

            string result = "";

            Process p;

            ProcessStartInfo psi = new ProcessStartInfo();

            psi.FileName = fileName;

            psi.Arguments = args;

            psi.WorkingDirectory = "...\\TempFolder";

            psi.UseShellExecute = false;

            psi.CreateNoWindow = true;

            psi.StandardOutputEncoding = System.Text.Encoding.UTF8;

            psi.RedirectStandardInput = true;

            psi.RedirectStandardOutput = true;

            psi.RedirectStandardError = true;

            p = Process.Start(psi);

            // After it gots here, process get stuck inside while loop
            ProcessManager.ThrottleProcess(p.Id , 1);

            try
            {
                string output = p.StandardOutput.ReadToEnd();

                p.WaitForExit();

                if (p.ExitCode != 0)
                    throw new Exception("Program returned with error code " + p.ExitCode);

                result = output.ToString();
            }
            catch (Exception ex)
            {
                result = ex.ToString();
            }
            finally
            {
                p.Close();
                p.Dispose();
            }

            return result;
        }

【问题讨论】:

  • 检查 CPU 使用率不是您的工作。如果你的程序需要 CPU,那就去做吧。您的操作系统是需要管理资源的操作系统。几乎所有现代 CPU 和操作系统都在改变 CPU 的速度,这取决于所需的性能。
  • @user6537157 问题是我在服务器上的程序,一旦启动进程,它就会使用 100%,因此会减慢其他进程。
  • 那你的程序还有其他问题。也许更好的是,您找出程序消耗如此多 CPU 时间的原因。但是不要在你的代码中建立一个“cpu 限制器”——它不会让你开心。
  • @user6537157 进程启动程序,而且那个程序不是我创建的,我怎么知道?
  • 您想限制其他程序?更糟糕的是,您不知道其他程序对您的“限制”有何反应。我的提示:给应用程序降低 cpu 优先级并尝试调查问题(可能与原始开发人员交谈或使用其他软件)。

标签: c# asp.net asp.net-mvc process


【解决方案1】:

原来你可以为一个进程设置亲和力。亲和力是您的过程将使用的核心数量。您唯一需要的就是为您的 Process 方法添加此字符串:

Process p = new Process();
p.ProcessorAffinity = (IntPtr)1; // or any number (your cores)

在我的情况下,它将 CPU 过载降至最低。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-01
    • 2016-12-30
    • 2021-08-19
    • 2015-08-02
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多