iconDreamine
← 목록

Dreamine.Threading.Windows

stablev1.0.1

Windows 전용 스레딩 확장 — Dispatcher 통합, Windows 이벤트 핸들링.

#cpu-affinity#csharp#dotnet#dreamine#threading#timer-resolution#windows#worker
TFM net8.0-windowsPackage Dreamine.Threading.Windows참조 Dreamine.MVVM.Core, Dreamine.Threading

Dreamine.Threading.Windows

Dreamine.Threading.Windows는 Dreamine.Threading을 위한 Windows 전용 스레딩 서비스 패키지입니다.

이 패키지는 CPU Affinity, Timer Resolution, Windows CPU 정보, 프로세스 CPU 사용률 측정 같은 플랫폼 의존 기능을 구현합니다.
Dreamine.Threading을 참조하며, Windows 데스크톱 애플리케이션에서 사용할 실제 구현체를 제공합니다.

➡️ English README

목적

Dreamine.Threading Core 패키지는 추상화와 스케줄링 정책을 정의합니다.
이 패키지는 그 추상화에 대한 Windows 구현을 제공합니다.

Dreamine.Threading
 ├─ IThreadAffinityService
 ├─ ITimerResolutionService
 ├─ ICpuUsageProvider
 └─ CPU/Core 관련 추상화

Dreamine.Threading.Windows
 ├─ WindowsThreadAffinityService
 ├─ WindowsTimerResolutionService
 ├─ WindowsCpuInfoProvider
 └─ WindowsProcessCpuUsageProvider

책임

이 패키지의 책임:

  • 현재 Windows Thread에 CPU Affinity 적용
  • 지원되는 환경에서 Timer Resolution 제어
  • Windows CPU 정보 제공
  • 현재 프로세스 CPU 사용률 측정
  • Windows 전용 등록 헬퍼 제공
  • P/Invoke 코드를 Core Threading 패키지 밖으로 분리

패키지 구조

Dreamine.Threading.Windows
├─ Native
│  ├─ Kernel32NativeMethods.cs
│  └─ WinMmNativeMethods.cs
│
├─ Services
│  ├─ WindowsCpuInfoProvider.cs
│  ├─ WindowsProcessCpuUsageProvider.cs
│  ├─ WindowsThreadAffinityService.cs
│  └─ WindowsTimerResolutionService.cs
│
└─ Registration
   └─ DreamineThreadingWindowsRegistration.cs

서비스

WindowsThreadAffinityService

구현 인터페이스:

IThreadAffinityService

Windows Native API를 사용해 현재 Thread에 CPU Affinity를 적용합니다.

CoreIndex = 2
 → 현재 Thread의 Affinity Mask를 CPU Core 2로 설정

WindowsTimerResolutionService

구현 인터페이스:

ITimerResolutionService

timeBeginPeriod, timeEndPeriod를 사용해 Timer Resolution을 제어합니다.

고정밀 Polling이 필요한 경우 사용할 수 있지만, Timer Resolution은 시스템 전체에 영향을 줄 수 있으므로 신중하게 사용해야 합니다.

WindowsCpuInfoProvider

Windows CPU 정보를 제공합니다.

Environment.ProcessorCount

WindowsProcessCpuUsageProvider

구현 인터페이스:

ICpuUsageProvider

현재 프로세스 CPU 사용률을 다음 정보를 기준으로 계산합니다.

Process.GetCurrentProcess().TotalProcessorTime
경과 시간
Environment.ProcessorCount

이 Provider는 AdaptiveCpuCyclePolicy에서 CPU 사용률이 높아질 때 동적 Delay를 적용하기 위해 사용됩니다.

Adaptive CPU Delay 연동

WindowsProcessCpuUsageProvider를 사용하면 0ms Worker도 CPU 사용률 기준으로 제어할 수 있습니다.

예시 동작:

CPU >= 70% -> 5ms Delay
CPU >= 50% -> 3ms Delay
CPU >= 30% -> 1ms Delay
CPU <  30% -> 0ms Delay

이 방식은 IntervalMs = 0이 필요한 FA 스타일 모니터링 루프에서 CPU 폭주를 막는 데 유용합니다.

등록

현재 등록 방식:

using Dreamine.Threading.Windows.Registration;

DreamineThreadingWindowsRegistration.Register();

이 호출은 다음 Windows 전용 서비스를 등록합니다.

IThreadAffinityService  -> WindowsThreadAffinityService
ITimerResolutionService -> WindowsTimerResolutionService
ICpuUsageProvider       -> WindowsProcessCpuUsageProvider
WindowsCpuInfoProvider

이 패키지는 다른 어셈블리에서 DMContainer를 partial class로 확장하지 않습니다. 등록은 별도의 Registration 클래스를 통해 제공합니다.

설계 메모

Windows 전용 API는 Dreamine.Threading Core 안에 들어가면 안 됩니다.

이 패키지는 다음 의존성 방향을 지키기 위해 존재합니다.

Dreamine.Threading
        ↑
Dreamine.Threading.Windows

Core 패키지는 플랫폼 독립성을 유지하고, 이 패키지는 Windows 전용 동작을 담당합니다.

검증 시나리오

다음 구성으로 검증했습니다.

High Adaptive Job: 5
High Raw Job:      5
Normal Job:        30
Total Job:         40

관찰된 동작:

전용 Worker에 CPU Affinity 적용
Adaptive Worker는 프로세스 CPU 사용률을 기준으로 Cycle 속도 감소
Raw 0ms Worker는 Full-speed로 동작
Normal Worker는 100ms Polling 유지
전체 CPU 사용률은 샘플 실행 기준 약 25~30%대로 안정적 유지

관련 패키지

Dreamine.Threading
Dreamine.Threading.Windows
Dreamine.Threading.Wpf

상태

구현됨:

  • Windows CPU Affinity Service
  • Windows Timer Resolution Service
  • Windows CPU 정보 Provider
  • Windows Process CPU Usage Provider
  • Windows Registration Helper

향후 계획:

  • Restore Token 기반 Affinity 복원
  • Timer Resolution Period 옵션화
  • 더 풍부한 CPU 사용률 지표
  • Core 0 제외 정책 옵션
  • Windows 전용 동작 통합 테스트

License

MIT License

구조 다이어그램

classDiagram
    class WindowsDispatcher {
        -SynchronizationContext _ctx
        +InvokeAsync(Action) Task
        +InvokeAsync~T~(Func~T~) Task~T~
        +CheckAccess() bool
        +BeginInvoke(Action) void
    }
    class WindowsHighResTimer {
        -IntPtr _timerHandle
        +IntervalMs double
        +Elapsed event
        +Start() void
        +Stop() void
        +IsRunning bool
    }
    class WindowsThreadPool {
        <<static>>
        +QueueWorkItem(WaitCallback) void
        +QueueWorkItem~T~(Action~T~, T) void
        +GetAvailableThreads() int
    }
    class NativeTimerWrapper {
        -uint _timerId
        +Resolution uint
        +Period uint
        +Tick event
        +Start() void
        +Stop() void
    }
    class IDispatcher {
        <<interface>>
    }
    IDispatcher <|.. WindowsDispatcher
    WindowsHighResTimer --> NativeTimerWrapper

API 문서

타입

DreamineThreadingWindowsRegistration

\if KO Windows 전용 Dreamine 스레딩 서비스 등록 API를 제공합니다. \endif \if EN Provides registration APIs for Windows-specific Dreamine threading services. \endif

Kernel32NativeMethods

\if KO Windows 스레드 작업을 위한 네이티브 kernel32.dll 메서드를 제공합니다. \endif \if EN Provides native kernel32.dll methods for Windows thread operations. \endif

WindowsCpuInfoProvider

\if KO Windows 스레딩 서비스에 CPU 정보를 제공합니다. \endif \if EN Provides CPU information for Windows threading services. \endif

WindowsProcessCpuUsageProvider

\if KO Windows에서 현재 프로세스의 CPU 사용률 정보를 제공합니다. \endif \if EN Provides CPU-usage information for the current process on Windows. \endif

WindowsThreadAffinityService

\if KO 현재 Windows 스레드에 CPU 선호도를 적용합니다. \endif \if EN Applies CPU affinity to the current Windows thread. \endif

WindowsTimerResolutionService

\if KO 고정밀 스레드 주기를 위해 Windows 타이머 해상도를 참조 카운트 방식으로 제어합니다. \endif \if EN Controls Windows timer resolution with reference counting for high-precision thread cycles. \endif

WinMmNativeMethods

\if KO 타이머 해상도 제어를 위한 네이티브 winmm.dll 메서드를 제공합니다. \endif \if EN Provides native winmm.dll methods for timer-resolution control. \endif

DreamineThreadingWindowsRegistration

Register Method

\if KO 아직 등록되지 않은 Windows CPU·선호도·타이머 서비스를 전역 컨테이너에 등록합니다. \endif \if EN Registers Windows CPU, affinity, and timer services in the global container when absent. \endif

Kernel32NativeMethods

GetCurrentThread Method

\if KO 현재 스레드의 의사 핸들을 가져옵니다. \endif \if EN Gets a pseudo handle for the current thread. \endif

반환: \if KO 현재 스레드를 나타내는 의사 핸들입니다. \endif \if EN A pseudo handle representing the current thread. \endif

SetThreadAffinityMask Method

\if KO 지정한 스레드에 프로세서 선호도 마스크를 설정합니다. \endif \if EN Sets a processor-affinity mask for the specified thread. \endif

threadHandle— \if KO 대상 스레드 핸들입니다. \endif \if EN The target thread handle. \endif
threadAffinityMask— \if KO 적용할 프로세서 선호도 마스크입니다. \endif \if EN The processor-affinity mask to apply. \endif

반환: \if KO 이전 선호도 마스크이며 호출 실패 시 0입니다. \endif \if EN The previous affinity mask, or zero when the call fails. \endif

WindowsCpuInfoProvider

GetLogicalProcessorCount Method

\if KO 환경의 논리 프로세서 수를 가져오며 비정상 값은 1로 보정합니다. \endif \if EN Gets the environment's logical processor count, normalizing invalid values to one. \endif

반환: \if KO 1 이상의 논리 프로세서 수입니다. \endif \if EN A logical processor count of at least one. \endif

IsValidCoreIndex Method

\if KO 코어 인덱스가 현재 논리 프로세서 범위에 속하는지 확인합니다. \endif \if EN Determines whether a core index is within the current logical-processor range. \endif

coreIndex— \if KO 검사할 0부터 시작하는 코어 인덱스입니다. \endif \if EN The zero-based core index to validate. \endif

반환: \if KO 유효하면 입니다. \endif \if EN when the index is valid. \endif

WindowsProcessCpuUsageProvider

#ctor Method

\if KO 현재 프로세스의 초기 CPU 시간과 시각으로 클래스의 새 인스턴스를 초기화합니다. \endif \if EN Initializes a new instance of from the current process's initial CPU time and timestamp. \endif

Dispose Method

\if KO 내부 핸들을 해제하며 정리 오류는 억제합니다. \endif \if EN Releases the underlying handle and suppresses cleanup errors. \endif

GetTotalCpuUsagePercent Method

\if KO 최소 200밀리초 표본 간격으로 현재 프로세스의 코어 정규화 CPU 사용률을 계산합니다. \endif \if EN Calculates core-normalized CPU usage for the current process using a minimum 200-millisecond sampling interval. \endif

반환: \if KO 0~100으로 제한된 CPU 사용률이며 너무 이른 호출이나 정리 후에는 마지막 값을 반환합니다. \endif \if EN CPU usage clamped to zero through 100; the last value is returned for early samples or after disposal. \endif

_disposed Field

\if KO disposed 값을 보관합니다. \endif \if EN Stores the disposed value. \endif

_lastCpuUsage Field

\if KO last Cpu Usage 값을 보관합니다. \endif \if EN Stores the last cpu usage value. \endif

_lastProcessorTime Field

\if KO last Processor Time 값을 보관합니다. \endif \if EN Stores the last processor time value. \endif

_lastTimestamp Field

\if KO last Timestamp 값을 보관합니다. \endif \if EN Stores the last timestamp value. \endif

_process Field

\if KO process 값을 보관합니다. \endif \if EN Stores the process value. \endif

_syncRoot Field

\if KO sync Root 값을 보관합니다. \endif \if EN Stores the sync root value. \endif

WindowsThreadAffinityService

ApplyToCurrentThread Method

\if KO 현재 Windows 스레드의 선호도 마스크를 지정한 단일 CPU 코어로 설정합니다. \endif \if EN Sets the current Windows thread's affinity mask to one specified CPU core. \endif

coreIndex— \if KO 현재 프로세스 비트 폭 안의 0부터 시작하는 CPU 코어 인덱스입니다. \endif \if EN The zero-based CPU core index within the current process bit width. \endif
ClearCurrentThreadAffinity Method

\if KO 현재 스레드의 CPU 선호도를 해제합니다. 현재 구현은 이전 마스크를 보존하지 않아 아무 작업도 하지 않습니다. \endif \if EN Clears CPU affinity from the current thread. The current implementation is a no-op because it does not retain the previous mask. \endif

WindowsTimerResolutionService

#ctor Method

\if KO 기본 1밀리초 주기로 클래스의 새 인스턴스를 초기화합니다. \endif \if EN Initializes a new instance of with the default one-millisecond period. \endif

#ctor Method

\if KO 지정한 주기로 클래스의 새 인스턴스를 초기화합니다. \endif \if EN Initializes a new instance of with the specified period. \endif

period— \if KO 밀리초 단위 타이머 해상도 주기이며 0은 1로 보정됩니다. \endif \if EN The timer-resolution period in milliseconds; zero is normalized to one. \endif
Begin Method

\if KO 사용 참조를 증가시키고 첫 참조에서 Windows 고정밀 타이머 해상도를 요청합니다. \endif \if EN Increments the usage reference and requests high-precision Windows timer resolution on the first reference. \endif

Dispose Method

\if KO 남은 모든 타이머 해상도 참조를 해제하고 서비스를 정리합니다. \endif \if EN Releases all remaining timer-resolution references and disposes the service. \endif

End Method

\if KO 사용 참조를 감소시키고 마지막 참조에서 Windows 타이머 해상도 요청을 해제합니다. \endif \if EN Decrements the usage reference and clears the Windows timer-resolution request on the final reference. \endif

ThrowIfDisposed Method

\if KO 타이머 해상도 서비스가 아직 정리되지 않았는지 확인합니다. \endif \if EN Verifies that the timer-resolution service has not been disposed. \endif

_disposed Field

\if KO disposed 값을 보관합니다. \endif \if EN Stores the disposed value. \endif

_period Field

\if KO period 값을 보관합니다. \endif \if EN Stores the period value. \endif

_referenceCount Field

\if KO reference Count 값을 보관합니다. \endif \if EN Stores the reference count value. \endif

_syncRoot Field

\if KO sync Root 값을 보관합니다. \endif \if EN Stores the sync root value. \endif

WinMmNativeMethods

timeBeginPeriod Method

\if KO 최소 타이머 해상도를 요청합니다. \endif \if EN Requests a minimum timer resolution. \endif

period— \if KO 밀리초 단위 요청 해상도입니다. \endif \if EN The requested resolution in milliseconds. \endif

반환: \if KO 성공 시 0, 실패 시 오류 코드입니다. \endif \if EN Zero on success; otherwise, an error code. \endif

timeEndPeriod Method

\if KO 이전에 요청한 타이머 해상도를 해제합니다. \endif \if EN Clears a previously requested timer resolution. \endif

period— \if KO 밀리초 단위 해제할 타이머 해상도입니다. \endif \if EN The timer resolution in milliseconds to clear. \endif

반환: \if KO 성공 시 0, 실패 시 오류 코드입니다. \endif \if EN Zero on success; otherwise, an error code. \endif