Microsoft MVP성태의 닷넷 이야기
WaitHandle.WaitOne 과 Stopwatch에 관한 질문 [링크 복사], [링크+제목 복사],
조회: 17131
글쓴 사람
윤용한 (yonghany at gmail.com)
홈페이지
첨부 파일
 
(연관된 글이 2개 있습니다.)

안녕하세요.
Stopwatch와 WaitOne에 대해 질문드립니다.
개발환경은 .NET 4.0이고 TPL을 사용 중입니다.
문제는 다음과 같습니다.
task가 매 1분마다 한번씩 서버에 데이터를 보내는데
이게 정확히 1분마다 수행되는게 아니고 시간이 점점 짧아집니다.
System.Thread.Timer를 이용해도 마찬가지로 약간의 밀리세컨드 오차가 발생하여 정확히 1분만다 수행이 안됩니다. 실행시간이 짧으면 괞찮겠지만 최소 16시간에서 36시간 동안 진행되는 작업이라, 시간이 흐를수록 오차가 점점 커져가서 16시간 정도 되면 거의 1시간 가량이 단축되어 버립니다..--;

오차를 줄이기 위해 매분마다 하는 작업시간도 계산해서 frequency에서 뺀 시간만큼 wait를 해도 오차가 줄어들긴하지만 없어지지는 않네요.

제 생각에는 Stopwatch는 HighResolution으로 계산이 되지만 WaitOne
에서 부동소수점이 절삭되어서 계속해서 오차가 생기는 거 같은데 (맞나요?)...

이러한 오차없이 정확한 시간에 수행되도록 하는 방법이 있나요?


TimeSpan frequency = new TimeSpan(0,1,0);
for (int step=1; step<960; step++)
{
  Stopwatch stopwatch = Stopwatch.StartNew();

  Log.InfoFormat("STEP, {0}, {1:00}:{2:00}", step, (int)(CurrentStep / 60.0), CurrentStep % 60.0);

  //
  // 작업수행 (여기서 걸리는 시간은 길어야 00:00:00.0120852 입니다)
  //
  stopwatch.Stop();

  // 여기서 wait하는 시간은 큰 차이가 없습니다.
  // 대략 00:00:59.9901087 정도
  // 하지만 WaitOne이 좀도 빨리 깨어나는 거 같습니다.
  Log.DebugFormat("MEASURE, {0}, WAIT={1}", stopwatch.Elapsed, (Frequency - stopwatch.Elapsed));
  token.WaitHandle.WaitOne(frequency - stopwatch.Elapased);
}

수행결과 : millisecond가 약간씩 틀려짐

2011-02-18 11:05:11,602 [10] INFO STEP, 1, 00:01
2011-02-18 11:06:11,603 [10] INFO STEP, 2, 00:02
2011-02-18 11:07:11,602 [10] INFO STEP, 3, 00:03
2011-02-18 11:08:11,602 [10] INFO STEP, 4, 00:04
2011-02-18 11:09:11,601 [10] INFO STEP, 5, 00:05
2011-02-18 11:10:11,600 [10] INFO STEP, 6, 00:06
2011-02-18 11:11:11,600 [10] INFO STEP, 7, 00:07
2011-02-18 11:12:11,599 [10] INFO STEP, 8, 00:08
2011-02-18 11:13:11,599 [10] INFO STEP, 9, 00:09
2011-02-18 11:14:11,599 [10] INFO STEP, 10, 00:10
2011-02-18 11:15:11,599 [10] INFO STEP, 11, 00:11
2011-02-18 11:16:11,598 [10] INFO STEP, 12, 00:12
2011-02-18 11:17:11,597 [10] INFO STEP, 13, 00:13
2011-02-18 11:18:11,597 [10] INFO STEP, 14, 00:14
2011-02-18 11:19:11,596 [10] INFO STEP, 15, 00:15
2011-02-18 11:20:11,596 [10] INFO STEP, 16, 00:16
2011-02-18 11:21:11,595 [10] INFO STEP, 17, 00:17
2011-02-18 11:22:11,595 [10] INFO STEP, 18, 00:18
2011-02-18 11:23:11,594 [10] INFO STEP, 19, 00:19
2011-02-18 11:24:11,593 [10] INFO STEP, 20, 00:20
2011-02-18 11:25:11,593 [10] INFO STEP, 21, 00:21
2011-02-18 11:26:11,592 [10] INFO STEP, 22, 00:22
2011-02-18 11:27:11,592 [10] INFO STEP, 23, 00:23
2011-02-18 11:28:11,591 [10] INFO STEP, 24, 00:24
2011-02-18 11:29:11,591 [10] INFO STEP, 25, 00:25
2011-02-18 11:30:11,590 [10] INFO STEP, 26, 00:26
2011-02-18 11:31:11,590 [10] INFO STEP, 27, 00:27
2011-02-18 11:32:11,589 [10] INFO STEP, 28, 00:28
2011-02-18 11:33:11,588 [10] INFO STEP, 29, 00:29
2011-02-18 11:34:11,588 [10] INFO STEP, 30, 00:30
2011-02-18 11:35:11,587 [10] INFO STEP, 31, 00:31
2011-02-18 11:36:11,587 [10] INFO STEP, 32, 00:32
2011-02-18 11:37:11,586 [10] INFO STEP, 33, 00:33
2011-02-18 11:38:11,586 [10] INFO STEP, 34, 00:34
2011-02-18 11:39:11,585 [10] INFO STEP, 35, 00:35

시간측정값
2011-02-18 11:05:11,613 [10] DEBUG MEASURE, 00:00:00.0111593, WAIT=00:00:59.9888403
2011-02-18 11:06:11,615 [10] DEBUG MEASURE, 00:00:00.0129216, WAIT=00:00:59.9870780
2011-02-18 11:07:11,613 [10] DEBUG MEASURE, 00:00:00.0111803, WAIT=00:00:59.9888193
2011-02-18 11:08:11,614 [10] DEBUG MEASURE, 00:00:00.0120852, WAIT=00:00:59.9879144
2011-02-18 11:09:11,614 [10] DEBUG MEASURE, 00:00:00.0131108, WAIT=00:00:59.9868892
2011-02-18 11:10:11,608 [10] DEBUG MEASURE, 00:00:00.0079609, WAIT=00:00:59.9920387
2011-02-18 11:11:11,609 [10] DEBUG MEASURE, 00:00:00.0089334, WAIT=00:00:59.9910662
2011-02-18 11:12:11,608 [10] DEBUG MEASURE, 00:00:00.0089188, WAIT=00:00:59.9910804
2011-02-18 11:13:11,610 [10] DEBUG MEASURE, 00:00:00.0114450, WAIT=00:00:59.9885546
2011-02-18 11:14:11,608 [10] DEBUG MEASURE, 00:00:00.0090173, WAIT=00:00:59.9909823
2011-02-18 11:15:11,609 [10] DEBUG MEASURE, 00:00:00.0102548, WAIT=00:00:59.9897448
2011-02-18 11:16:11,609 [10] DEBUG MEASURE, 00:00:00.0111414, WAIT=00:00:59.9888582
2011-02-18 11:17:11,608 [10] DEBUG MEASURE, 00:00:00.0110511, WAIT=00:00:59.9889485
2011-02-18 11:18:11,609 [10] DEBUG MEASURE, 00:00:00.0120560, WAIT=00:00:59.9879436
2011-02-18 11:19:11,608 [10] DEBUG MEASURE, 00:00:00.0120682, WAIT=00:00:59.9879314
2011-02-18 11:20:11,604 [10] DEBUG MEASURE, 00:00:00.0086704, WAIT=00:00:59.9913292
2011-02-18 11:21:11,603 [10] DEBUG MEASURE, 00:00:00.0081886, WAIT=00:00:59.9918110
2011-02-18 11:22:11,604 [10] DEBUG MEASURE, 00:00:00.0089399, WAIT=00:00:59.9910593
2011-02-18 11:23:11,604 [10] DEBUG MEASURE, 00:00:00.0099999, WAIT=00:00:59.9899997
2011-02-18 11:24:11,603 [10] DEBUG MEASURE, 00:00:00.0100089, WAIT=00:00:59.9899907
2011-02-18 11:25:11,604 [10] DEBUG MEASURE, 00:00:00.0110559, WAIT=00:00:59.9889437
2011-02-18 11:26:11,603 [10] DEBUG MEASURE, 00:00:00.0110989, WAIT=00:00:59.9889007
2011-02-18 11:27:11,599 [10] DEBUG MEASURE, 00:00:00.0071067, WAIT=00:00:59.9928929
2011-02-18 11:28:11,603 [10] DEBUG MEASURE, 00:00:00.0121991, WAIT=00:00:59.9878001
2011-02-18 11:29:11,604 [10] DEBUG MEASURE, 00:00:00.0130569, WAIT=00:00:59.9869427
2011-02-18 11:30:11,599 [10] DEBUG MEASURE, 00:00:00.0090432, WAIT=00:00:59.9909564
2011-02-18 11:31:11,599 [10] DEBUG MEASURE, 00:00:00.0090979, WAIT=00:00:59.9909017
2011-02-18 11:32:11,599 [10] DEBUG MEASURE, 00:00:00.0100611, WAIT=00:00:59.9899385
2011-02-18 11:33:11,598 [10] DEBUG MEASURE, 00:00:00.0100315, WAIT=00:00:59.9899680
2011-02-18 11:34:11,599 [10] DEBUG MEASURE, 00:00:00.0111119, WAIT=00:00:59.9888877
2011-02-18 11:35:11,598 [10] DEBUG MEASURE, 00:00:00.0118449, WAIT=00:00:59.9881547
2011-02-18 11:36:11,599 [10] DEBUG MEASURE, 00:00:00.0121087, WAIT=00:00:59.9878909
2011-02-18 11:37:11,593 [10] DEBUG MEASURE, 00:00:00.0072878, WAIT=00:00:59.9927114
2011-02-18 11:38:11,594 [10] DEBUG MEASURE, 00:00:00.0079937, WAIT=00:00:59.9920059
2011-02-18 11:39:11,594 [10] DEBUG MEASURE, 00:00:00.0092098, WAIT=00:00:59.9907898
2011-02-18 11:40:11,593 [10] DEBUG MEASURE, 00:00:00.0091826, WAIT=00:00:59.9908170
2011-02-18 11:41:11,594 [10] DEBUG MEASURE, 00:00:00.0100944, WAIT=00:00:59.9899052
2011-02-18 11:42:11,593 [10] DEBUG MEASURE, 00:00:00.0099744, WAIT=00:00:59.9900252
2011-02-18 11:43:11,599 [10] DEBUG MEASURE, 00:00:00.0162488, WAIT=00:00:59.9837508
2011-02-18 11:44:11,593 [10] DEBUG MEASURE, 00:00:00.0110981, WAIT=00:00:59.9889015
2011-02-18 11:45:11,594 [10] DEBUG MEASURE, 00:00:00.0120811, WAIT=00:00:59.9879184
2011-02-18 11:46:11,594 [10] DEBUG MEASURE, 00:00:00.0130508, WAIT=00:00:59.9869488
2011-02-18 11:47:11,593 [10] DEBUG MEASURE, 00:00:00.0130893, WAIT=00:00:59.9869103
2011-02-18 11:48:11,589 [10] DEBUG MEASURE, 00:00:00.0090250, WAIT=00:00:59.9909750
2011-02-18 11:49:11,588 [10] DEBUG MEASURE, 00:00:00.0091449, WAIT=00:00:59.9908547
2011-02-18 11:50:11,589 [10] DEBUG MEASURE, 00:00:00.0101693, WAIT=00:00:59.9898307
2011-02-18 11:51:11,588 [10] DEBUG MEASURE, 00:00:00.0098909, WAIT=00:00:59.9901087
2011-02-18 11:52:11,589 [10] DEBUG MEASURE, 00:00:00.0110673, WAIT=00:00:59.9889323
2011-02-18 11:53:11,589 [10] DEBUG MEASURE, 00:00:00.0120986, WAIT=00:00:59.9879010



[연관 글]






[최초 등록일: ]
[최종 수정일: 2/18/2011]


비밀번호

댓글 작성자
 



2011-02-18 04시10분
윈도우 운영체제 자체가 RTOS가 아니다 보니, 정확한 시간 구현은 무리가 있을 것입니다. 어떻게 해서든 정밀도를 높이려면 스레드 우선순위를 높인다거나, 아예 DeviceDriver를 하나 제작해서 클록 인터럽트마다 정확하게 이벤트를 보내주는 것을 만들어야 할 것입니다. 그렇게까지 하는 것은 좀 어려울 것 같고. ^^

대신 중간 중간 현재의 시간값을 가지고 보정을 해줘야 하지 않을까 싶은데요. 검색해 보니.. 다음의 글 같은 것도 나오는군요.

C# timer synchronized with Datetime.Now
; http://stackoverflow.com/questions/2996236/c-timer-synchronized-with-datetime-now
정성태
2011-02-18 05시19분
[윤용한] 답변 감사합니다.
아무리 오차를 줄이려해도 0.000481 milliseconds 씩 계속해서 오차가 발생했었는데
검색하던 중에 multimedia timer를 이용한 글을 보고 적용해보니
99.999999% 정확하게 움직이고 있습니다^^.
가끔 0.000001 오차가 생기지만 그 다음 tick callback에서는 보정되어 정확하게 움직입니다.
16:12:15,735 [12] INFO STEP, 87, 01:27
16:13:15,736 [12] INFO STEP, 88, 01:28 *** 오차발생
16:14:15,735 [12] INFO STEP, 89, 01:29 *** 보정됨
16:15:15,735 [12] INFO STEP, 90, 01:30
16:16:15,735 [12] INFO STEP, 91, 01:31
16:17:15,735 [12] INFO STEP, 92, 01:32
16:18:15,735 [12] INFO STEP, 93, 01:33
16:19:15,735 [12] INFO STEP, 94, 01:34
16:20:15,735 [12] INFO STEP, 95, 01:35

The Multimedia Timer for the .NET Framework
http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx
[guest]
2011-02-20 09시57분
오~~~ 윤용한님 덕분에 새로운 것을 알았군요. ^^ 멀티미디어 타이머가 간간이 게임 프로그래머들 글에서 나오는 것을 읽긴 했었는데, 정확히 어떤 역할을 하는지는 모르고 있었습니다. 그 한 가지 예로 이해가 팍팍~~~ 되는군요. ^^ 너무 너무 감사드립니다. (오늘은 밥을 안 먹어도 배부를 것 같군요. ^^)
정성태

... 16  17  18  19  20  21  22  23  [24]  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
5319권대현4/10/20206277C++(UWP)Dll에서 C#(UWP)Dll 호출이 가능한가요? [1]
5318이승준4/9/20207136동영상 관련 업계 근황? 입니다. [1]
5317kskk...4/7/20209158OpenCV 이용 해상도 설정 질문 입니다.. [3]
5316윤현수4/7/20206389pipe 비동기방식 질문 [1]파일 다운로드1
53154/6/20207064dll파일 로드 원리? 부분에서 도움받고싶습니다. [3]
5314강성욱3/31/20208942메서드 내에서 await 2번 등장할 때의 이해 [11]파일 다운로드1
5313강성욱3/27/20206741await 2번 [1]
53121a2a...3/20/20206526Re raw data write 질문 관련 [1]파일 다운로드1
53111a2a...3/20/20207313Raw data write 관련 질문 [1]파일 다운로드1
5310아스파넬3/15/202073391초에 5회 함수호출 제한 관련 질문입니다. [1]
5309하태3/11/20209230안녕하십니까. c# Winform UI 질문드리겠습니다! [3]파일 다운로드1
5308질문3/9/20208041Window XP SP3 32bit 환경(Window Update 모두 완료)에서 .Net Framework 4.0.3 으로 빌드된 .dll 파일 gacutil.exe 등록 관련 문의 [5]
5306개발자3/9/20206906C#을 통해 인터넷 접속 가능한 이더넷을 선택할 수 있는지요? [1]
5305JaeS...3/9/20206587RAW파일 생성 질문드립니다 [8]파일 다운로드1
5303궁금하당2/27/20208907C#에서 C++ DLL읽기 (아래 글쓴이) [1]
5302궁금하당2/27/202010968C#에서 C++ DLL호출 ('PInvokeStackImbalance') [4]파일 다운로드1
5301질문합니...2/27/20206440소켓 대량 데이터 디자인 문의 [1]
5300nals...2/27/20207062vs2013에서 BinaryFormatter Serialize 후 vs2015에서 Deserialize시 예외 발생 [3]파일 다운로드1
5298질문2/26/20208452.lic 파일에 대해 질문 있습니다. [9]
5297임한승2/26/20206020vs2013에서 BinaryFormatter Serialize 후 vs2015에서 Deserialize시 예외 발생 건 [1]파일 다운로드1
5295나그네2/25/20207417클라이언트 PC 정보 조회관련.. [2]
5294닷넷초보ㅠ2/25/20207400윈폼으로 socket통신프로그램 만든후 release로 디버깅한 실행파일을 다른컴퓨터에서 실행할때 반응이없어요 [1]
5293탱코2/21/20207314검색을 하고 싶은데 어떻게 검색을 해야 할 지 모르겠습니다. [1]
5292아부리2/19/20207210XingApiNet 관련 질문 [3]
5291지현명2/15/20207970JsonConvert.Serialize 하고 Deserialize 할때 간헐적으로 한글 깨짐 현상 문의 합니다. [3]
5290베도빈2/15/20207325직접 제작한 사용자 정의 콘트롤 DLL, 실행파일에 포함시켜 배포할 수 있을까요? [1]
... 16  17  18  19  20  21  22  23  [24]  25  26  27  28  29  30  ...