Coding Memo
Environment.TickCount 오버플로우 (대안) 본문
C#에서 어떤 타이머를 구현하거나 실행 예약 등을 할 때 Environment.TickCount를 이용할 수 있다.
(물론 타이머는 기본적으로 제공하기는 한다. (System.Timers.Timer 등))
https://learn.microsoft.com/en-us/dotnet/api/system.environment.tickcount?view=net-8.0
기계어로 번역되어 있는 부분이 많이 보이는데 항상 이해을 하지 못할 정도로 제대로 번역이 되어 있지 않은 경우가 많은 것 같다.
위 문서에도 나와 있지만, TickCount는 부호가 있는 32-bit 정수(32-bit signed integer)로 표현이 된다. 따라서 만약 int.Max( 2147483647)이후에는 int.Min( -2147483648)값이 되고야 만다.
실제 위 문서에서도 아래와 같이 사이클이 약 49.8일이라고 나와 있다.
위 TickCount를 계속해서 실행실행되고 있는 서버 등에서 사용한다면 큰일이 날 것이다.
그렇다면 이에 대한 대안이 무엇이 있을까?
1. Environment.TickCount64 사용
말그대로 Environment.TickCount와 같지만 32비트보다 훨씬 큰 수를 표현할 수 있는 long 타입(64-bit)의 tick을 가져올 수 있다. 참고로 int값이 최장 대략 49.8일이었지만, long 타입이라면 엄청나게 길다. (계산은 따로 안하겠다.)
long now = Environment.TickCount64;
그냥 단순히 이걸 사용하면 되겠네!
할 수도 있지만 아쉽게도 TickCount64는 일부 버전에서만 사용 가능하다. (물론 only Windows라면 사용해도 좋겠다.)
(딱 봐도, windows api인 GetTickCount64를 내부적으로 호출하여 가져오는 것처럼 보인다.)
ref: https://learn.microsoft.com/ko-kr/dotnet/api/system.environment.tickcount64?view=net-8.0
아쉽게도 .NET Standard에서는 지원하지 않는다.
2. Stopwatch 사용
Stopwatch 클래스는 말 그대로 스톱워치를 구현하는 클래스이다. 시작(Start)하여 시간을 측정(ElapsedMilliseconds)할 수 있고 정지(Stop) 시킬 수도 있고 리셋(Reset) 시킬 수도 있다. (ElapsedTick으로 tick을 가져올 수도 있다.)
주목해야 할 점은 시간 측정 단위가 Milliseconds 및 tick이고, 64-bit 정수라는 것이다.
Stopwatch 클래스는 System.Diagnostics 네임스페이스에 있다.
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start(); // 시간 측정 시작
long now = stopwatch.ElapsedMilliseconds; // 경과 시간 가져오기
TimeSpan now_timespan = stopwatch.Elapsed; // 경과 시간 가져오기 (TimeSpan)
long elapsed_tick = stopwatch.ElapsedTicks; // 경과 tick 가져오기
stopwatch.Stop(); // 시간 측정 정지
stopwatch.Reset(); // 스톱워치 리셋
이 클래스는 대부분의 버전에서 사용 가능하다.
ref: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=net-8.0
Note: 일반적으로 ElapsedMilliseconds는 경과한 시간을 밀리초 단위로 반환하는 과정에서 계산 시간이 걸릴 수 있어 약간의 정확도가 떨어 질 수도 있다. (ElapsedTicks가 좀 더 정확하지만, 시스템마다 차이가 있다.)
어떤 작업 예약을 처리하는 클래스를 만들어보면서 위 내용을 찾아보게 되었다. 타겟 프레임워크가 .NET Standard 2.1이라 Stopwatch를 사용하기로 했다.
아직 생각하고 있는 것은, Milliseconds로 할 것인지, Tick으로 할 것인지이다...
'Language > C#' 카테고리의 다른 글
Entity Framework - virtual 키워드 (1) | 2023.12.31 |
---|---|
BitConverter, 직렬화 (little-endian, big-endian) (0) | 2023.12.06 |
싱글턴 멀티 스레드 주의 (1) | 2023.11.23 |
에코 서버 (TcpClient, async/await 이용) (0) | 2023.11.09 |
[C#] .NET 환경에서 지원하는 C# 버전 (0) | 2023.08.14 |