728x90
반응형
728x170
▶ 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
반응형
그리드형(광고전용)
'C# > Common' 카테고리의 다른 글
[C#/COMMON] 파일 잠금 여부 구하기 (0) | 2019.10.06 |
---|---|
[C#/COMMON] DataTable 클래스 : 객체 컬렉션 구하기 (0) | 2019.09.20 |
[C#/COMMON] IDataReader 인터페이스 : 레코드를 객체로 변환하기 (0) | 2019.09.20 |
[C#/COMMON] PropertyInfo 클래스 : 타입의 속성 정보 배열 구하기 (0) | 2019.09.20 |
[C#/COMMON] 프로세스 CPU 사용률 제한하기 (0) | 2019.09.04 |
[C#/COMMON] 프로세스 CPU 사용률 제한하기 (0) | 2019.09.04 |
[C#/COMMON] PerformanceCounter 클래스 : 인스턴스명으로 프로세스 CPU 사용률 구하기 (0) | 2019.09.04 |
[C#/COMMON] PerformanceCounter 클래스 : 프로세스명으로 인스턴스명 딕셔너리 구하기 (0) | 2019.09.04 |
[C#/COMMON] Array 클래스 : Resize 정적 메소드를 사용해 배열 크기 변경하기 (0) | 2019.08.30 |
[C#/COMMON] Marshal 클래스 : 구조체 바이트 배열/객체 구하기 (0) | 2019.08.29 |
[C#/COMMON] Marshal 클래스 : 비관리 메모리 할당하기 (0) | 2019.08.29 |
댓글을 달아 주세요