첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

TestSolution.zip
다운로드

▶ ProcessHelper.cs

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace TestProject
{
    /// <summary>
    /// 프로세스 헬퍼
    /// </summary>
    public static class ProcessHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 스레드 열기 - OpenThread(threadAccess, inheritHandle, threadID)

        /// <summary>
        /// 스레드 열기
        /// </summary>
        /// <param name="threadAccess">스레드 액세스</param>
        /// <param name="inheritHandle">상속 핸들</param>
        /// <param name="threadID">스레드 ID</param>
        /// <returns>스레드 핸들</returns>
        [DllImport("kernel32.dll")]
        private static extern IntPtr OpenThread(ThreadAccess threadAccess, bool inheritHandle, uint threadID);

        #endregion
        #region 스레드 실행 일시 중지하기 - SuspendThread(threadHandle)

        /// <summary>
        /// 스레드 실행 일시 중지하기
        /// </summary>
        /// <param name="threadHandle">스레드 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("kernel32.dll")]
        private static extern uint SuspendThread(IntPtr threadHandle);

        #endregion
        #region 스레드 다시 실행하기 - ResumeThread(threadHandle)

        /// <summary>
        /// 스레드 다시 실행하기
        /// </summary>
        /// <param name="threadHandle">스레드 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("kernel32.dll")]
        private static extern int ResumeThread(IntPtr threadHandle);

        #endregion
        #region 핸들 닫기 - CloseHandle(threadHandle)

        /// <summary>
        /// 핸들 닫기
        /// </summary>
        /// <param name="threadHandle">스레드 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("kernel32.dll")]
        private static extern int CloseHandle(IntPtr threadHandle);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 프로세스 실행 일시 중지하기 - SuspendProcess(processID)

        /// <summary>
        /// 프로세스 실행 일시 중지하기
        /// </summary>
        /// <param name="processID">프로세스 ID</param>
        public static void SuspendProcess(int processID)
        {
            Process process = Process.GetProcessById(processID);

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

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

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

                SuspendThread(threadHandle);

                CloseHandle(threadHandle);
            }
        }

        #endregion
        #region 프로세스 다시 실행하기 - ResumeProcess(processiD)

        /// <summary>
        /// 프로세스 다시 실행하기
        /// </summary>
        /// <param name="processiD">프로세스 ID</param>
        public static void ResumeProcess(int processiD)
        {
            Process process = Process.GetProcessById(processiD);

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

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

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

                var suspendCount = 0;

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

                CloseHandle(threadHandle);
            }
        }

        #endregion

        #region 프로세스 조절하기 - ThrottleProcess(processID, limitCPURate)

        /// <summary>
        /// 프로세스 조절하기
        /// </summary>
        /// <param name="processID">프로세스 ID</param>
        /// <param name="limitUsage">제한 사용률</param>
        public static void ThrottleProcess(int processID, double limitUsage)
        {
            Process process = Process.GetProcessById(processID);

            string instanceName = process.ProcessName;

            PerformanceCounter counter = new PerformanceCounter("Process", "% Processor Time", instanceName);

            int interval = 100;

            while(true)
            {
                Thread.Sleep(interval);

                float currentUsage = counter.NextValue() / Environment.ProcessorCount;

                if(currentUsage < limitUsage)
                {
                    continue;
                }

                double suspensionTime = (currentUsage - limitUsage) / currentUsage * interval;

                SuspendProcess(processID);

                Thread.Sleep((int)suspensionTime);

                ResumeProcess(processID);
            }
        }

        #endregion
    }
}

 

728x90

 

▶ Program.cs

using System;
using System.Diagnostics;
 
namespace TestProject
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 프로세스
        /// </summary>
        private static Process _process = null;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private static void Main()
        {
            Console.CancelKeyPress += Console_CancelKeyPress;

            _process = new Process();

            _process.EnableRaisingEvents   = false;
            _process.StartInfo.FileName    = "TestWorker.exe";
            _process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            _process.Start();

            _process.PriorityClass = ProcessPriorityClass.BelowNormal;

            ProcessHelper.ThrottleProcess(_process.Id, 0.3);
        }

        #endregion

        #region 콘솔 취소 키 PRESS 처리하기 - Console_CancelKeyPress(sender, e)

        /// <summary>
        /// 콘솔 취소 키 PRESS 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            ProcessHelper.ResumeProcess(_process.Id);

            _process.Kill();
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by 사용자 icodebroker
TAG , ,

댓글을 달아 주세요