C#で使える1msタイマーを探す

# 調査内容
C#かつWindowsで1msのタイマーを使いたい。Threading.TimerやTask.Delay(1)では最短でも15msになるっぽいので他の方法を調べた。

# 環境

- Intel Core i5-8265U CPU @ 1.60GHz 1.80 GHz
- Windows 10 Pro 22H2
- C#, .NET Framework 4.6.2, Debug build
- Visual Studio Community 2022 (64-bit) Version 17.8.5
- 調査日：2024年5月6日
    - 2024年5月12日、追加調査。WaitableTimer, WaitableTimerExについて。

# テストコード

https://github.com/tosh-coding/AsyncFiberWorks/blob/010cc68dbedda83dc6f58d75665d143a933dc5b5/src/AsyncFiberWorksTests/TimerPrecisionTests.cs

1ms間隔の繰り返しタイマーを30回実行、毎回経過時間を取得してバッファリングする。最後に時間を出力する。

※私自身が作成中のライブラリのテストコードの一部として実装しました。

### 追加調査分

2024年5月12日、WaitableTimer, WaitableTimerEx他を追加：
- https://github.com/tosh-coding/AsyncFiberWorks/commit/16b05e2812c74b09bca49bc4c52885c13f2b4bca
- https://github.com/tosh-coding/AsyncFiberWorks/commit/65d3f67b90b9e49285eeaeda7a0c48a673c662b0

※時間計測する分にはとりあえず動いていますが怪しいところ満載です。エラーチェックや排他制御、リソース破棄方法などなど。ご注意ください。（怪しい箇所例：Unresister関数の引数はnullが正しかったのかもしれない）

2024年5月19日追記： RegisteredWaitHandle.Unregisterの引数は登録解除通知先でした。通知不要ならnullが正しいです。上記テストコードでは適当にその辺のwaitHandleを入れていますが無意味です。


# テストコードの結果出力

## NG: Task.Delay(1) with timeBeginPeriod
15msかかる。

```
 TaskDelayWithTimeBeginPeriod
   Source: TimerPrecisionTests.cs line 80
   Duration: 471 ms

  Standard Output: 
00:00:00.0044867 - 0ms
00:00:00.0045087 - 0.022ms
00:00:00.0214800 - 16.9713ms
00:00:00.0374901 - 16.0101ms
00:00:00.0514713 - 13.9812ms
00:00:00.0674196 - 15.9483ms
00:00:00.0833689 - 15.9493ms
00:00:00.0997226 - 16.3537ms
00:00:00.1146312 - 14.9086ms
00:00:00.1306641 - 16.0329ms
00:00:00.1461151 - 15.451ms
00:00:00.1606642 - 14.5491ms
00:00:00.1765523 - 15.8881ms
00:00:00.1925507 - 15.9984ms
00:00:00.2084939 - 15.9432ms
00:00:00.2244693 - 15.9754ms
00:00:00.2394697 - 15.0004ms
00:00:00.2554995 - 16.0298ms
00:00:00.2715304 - 16.0309ms
00:00:00.2856750 - 14.1446ms
00:00:00.3025209 - 16.8459ms
00:00:00.3176596 - 15.1387ms
00:00:00.3334724 - 15.8128ms
00:00:00.3497848 - 16.3124ms
00:00:00.3637904 - 14.0056ms
00:00:00.3796537 - 15.8633ms
00:00:00.3956148 - 15.9611ms
00:00:00.4126156 - 17.0008ms
00:00:00.4270422 - 14.4266ms
00:00:00.4433888 - 16.3466ms
```

## NG: System.Threading.Timer
15msかかる。
```
 ThreadingTimerSingle
   Source: TimerPrecisionTests.cs line 59
   Duration: 479 ms

  Standard Output: 
00:00:00.0135094 - 0ms
00:00:00.0281614 - 14.652ms
00:00:00.0439040 - 15.7426ms
00:00:00.0595244 - 15.6204ms
00:00:00.0750791 - 15.5547ms
00:00:00.0902067 - 15.1276ms
00:00:00.1054955 - 15.2888ms
00:00:00.1213688 - 15.8733ms
00:00:00.1368003 - 15.4315ms
00:00:00.1514577 - 14.6574ms
00:00:00.1666819 - 15.2242ms
00:00:00.1821015 - 15.4196ms
00:00:00.1975937 - 15.4922ms
00:00:00.2126568 - 15.0631ms
00:00:00.2280949 - 15.4381ms
00:00:00.2434886 - 15.3937ms
00:00:00.2587170 - 15.2284ms
00:00:00.2741257 - 15.4087ms
00:00:00.2900282 - 15.9025ms
00:00:00.3059636 - 15.9354ms
00:00:00.3219888 - 16.0252ms
00:00:00.3377328 - 15.744ms
00:00:00.3532917 - 15.5589ms
00:00:00.3684084 - 15.1167ms
00:00:00.3842955 - 15.8871ms
00:00:00.3998414 - 15.5459ms
00:00:00.4152891 - 15.4477ms
00:00:00.4311181 - 15.829ms
00:00:00.4463831 - 15.265ms
00:00:00.4617106 - 15.3275ms
```

## NG: System.Threading.Timer with timeBeginPeriod(1)
15msかかる。
```
 ThreadingTimerWithTimeBeginPeriod
   Source: TimerPrecisionTests.cs line 69
   Duration: 480 ms

  Standard Output: 
00:00:00.0117175 - 0ms
00:00:00.0256060 - 13.8885ms
00:00:00.0409010 - 15.295ms
00:00:00.0559364 - 15.0354ms
00:00:00.0719063 - 15.9699ms
00:00:00.0874985 - 15.5922ms
00:00:00.1032545 - 15.756ms
00:00:00.1191317 - 15.8772ms
00:00:00.1352911 - 16.1594ms
00:00:00.1510995 - 15.8084ms
00:00:00.1663257 - 15.2262ms
00:00:00.1813494 - 15.0237ms
00:00:00.1972766 - 15.9272ms
00:00:00.2132895 - 16.0129ms
00:00:00.2279514 - 14.6619ms
00:00:00.2440622 - 16.1108ms
00:00:00.2599993 - 15.9371ms
00:00:00.2757875 - 15.7882ms
00:00:00.2917165 - 15.929ms
00:00:00.3077084 - 15.9919ms
00:00:00.3216536 - 13.9452ms
00:00:00.3375781 - 15.9245ms
00:00:00.3531407 - 15.5626ms
00:00:00.3701289 - 16.9882ms
00:00:00.3850495 - 14.9206ms
00:00:00.3999899 - 14.9404ms
00:00:00.4168884 - 16.8985ms
00:00:00.4309048 - 14.0164ms
00:00:00.4468756 - 15.9708ms
00:00:00.4628308 - 15.9552ms
```

## △： Thread.Sleep(1) with timeBeginPeriod(1)
2msかかる。まぁ15msよりは良い。
```
 ThreadSleepWithTimeBeginPeriod
   Source: TimerPrecisionTests.cs line 106
   Duration: 63 ms

  Standard Output: 
00:00:00.0059333 - 0ms
00:00:00.0079711 - 2.0378ms
00:00:00.0099874 - 2.0163ms
00:00:00.0119968 - 2.0094ms
00:00:00.0139857 - 1.9889ms
00:00:00.0159706 - 1.9849ms
00:00:00.0179525 - 1.9819ms
00:00:00.0189903 - 1.0378ms
00:00:00.0207256 - 1.7353ms
00:00:00.0219069 - 1.1813ms
00:00:00.0238829 - 1.976ms
00:00:00.0258931 - 2.0102ms
00:00:00.0278998 - 2.0067ms
00:00:00.0299555 - 2.0557ms
00:00:00.0318559 - 1.9004ms
00:00:00.0338743 - 2.0184ms
00:00:00.0358762 - 2.0019ms
00:00:00.0379291 - 2.0529ms
00:00:00.0398584 - 1.9293ms
00:00:00.0418397 - 1.9813ms
00:00:00.0438405 - 2.0008ms
00:00:00.0448831 - 1.0426ms
00:00:00.0468855 - 2.0024ms
00:00:00.0479169 - 1.0314ms
00:00:00.0499995 - 2.0826ms
00:00:00.0519117 - 1.9122ms
00:00:00.0531469 - 1.2352ms
00:00:00.0552734 - 2.1265ms
00:00:00.0572860 - 2.0126ms
00:00:00.0592629 - 1.9769ms
```

## △： Thread.Sleep with NtSetTimerResolution(1ms)
2msかかる。15msよりはマシ。
```
 ThreadSleepWithNtSetTimerResolution1000us
   Source: TimerPrecisionTests.cs line 140
   Duration: 60 ms

  Standard Output: 
00:00:00.0005765 - 0ms
00:00:00.0027351 - 2.1586ms
00:00:00.0048058 - 2.0707ms
00:00:00.0067953 - 1.9895ms
00:00:00.0087674 - 1.9721ms
00:00:00.0107562 - 1.9888ms
00:00:00.0127583 - 2.0021ms
00:00:00.0145554 - 1.7971ms
00:00:00.0165451 - 1.9897ms
00:00:00.0184457 - 1.9006ms
00:00:00.0204764 - 2.0307ms
00:00:00.0217482 - 1.2718ms
00:00:00.0230387 - 1.2905ms
00:00:00.0250168 - 1.9781ms
00:00:00.0270158 - 1.999ms
00:00:00.0290066 - 1.9908ms
00:00:00.0309821 - 1.9755ms
00:00:00.0328352 - 1.8531ms
00:00:00.0347206 - 1.8854ms
00:00:00.0366985 - 1.9779ms
00:00:00.0387195 - 2.021ms
00:00:00.0406901 - 1.9706ms
00:00:00.0426877 - 1.9976ms
00:00:00.0446833 - 1.9956ms
00:00:00.0466795 - 1.9962ms
00:00:00.0486872 - 2.0077ms
00:00:00.0506315 - 1.9443ms
00:00:00.0526967 - 2.0652ms
00:00:00.0546414 - 1.9447ms
00:00:00.0566626 - 2.0212ms
```

## △： Thread.Sleep with NtSetTimerResolution(0.999ms)
1.1ms～2msでぶれる。15msよりはマシ。
```
 ThreadSleepWithNtSetTimerResolution999us
   Source: TimerPrecisionTests.cs line 170
   Duration: 57 ms

  Standard Output: 
00:00:00.0028348 - 0ms
00:00:00.0040295 - 1.1947ms
00:00:00.0060565 - 2.027ms
00:00:00.0080522 - 1.9957ms
00:00:00.0100330 - 1.9808ms
00:00:00.0120344 - 2.0014ms
00:00:00.0140126 - 1.9782ms
00:00:00.0151727 - 1.1601ms
00:00:00.0170409 - 1.8682ms
00:00:00.0190552 - 2.0143ms
00:00:00.0200753 - 1.0201ms
00:00:00.0213573 - 1.282ms
00:00:00.0230668 - 1.7095ms
00:00:00.0252250 - 2.1582ms
00:00:00.0263784 - 1.1534ms
00:00:00.0283597 - 1.9813ms
00:00:00.0303843 - 2.0246ms
00:00:00.0323901 - 2.0058ms
00:00:00.0343101 - 1.92ms
00:00:00.0354465 - 1.1364ms
00:00:00.0372733 - 1.8268ms
00:00:00.0393043 - 2.031ms
00:00:00.0413524 - 2.0481ms
00:00:00.0432779 - 1.9255ms
00:00:00.0452992 - 2.0213ms
00:00:00.0472932 - 1.994ms
00:00:00.0484810 - 1.1878ms
00:00:00.0504733 - 1.9923ms
00:00:00.0520269 - 1.5536ms
00:00:00.0532913 - 1.2644ms
```

## △： Thread.Sleep with NtSetTimerResolution(0.5ms)
だいたい1.5ms以下。15msよりはマシ。
```
 ThreadSleepWithNtSetTimerResolution500us
   Source: TimerPrecisionTests.cs line 150
   Duration: 64 ms

  Standard Output: 
00:00:00.0004372 - 0ms
00:00:00.0015903 - 1.1531ms
00:00:00.0033344 - 1.7441ms
00:00:00.0048311 - 1.4967ms
00:00:00.0060917 - 1.2606ms
00:00:00.0073090 - 1.2173ms
00:00:00.0085527 - 1.2437ms
00:00:00.0100163 - 1.4636ms
00:00:00.0113813 - 1.365ms
00:00:00.0125909 - 1.2096ms
00:00:00.0141024 - 1.5115ms
00:00:00.0155192 - 1.4168ms
00:00:00.0166976 - 1.1784ms
00:00:00.0182359 - 1.5383ms
00:00:00.0194805 - 1.2446ms
00:00:00.0207307 - 1.2502ms
00:00:00.0221555 - 1.4248ms
00:00:00.0236672 - 1.5117ms
00:00:00.0249467 - 1.2795ms
00:00:00.0261518 - 1.2051ms
00:00:00.0274328 - 1.281ms
00:00:00.0287705 - 1.3377ms
00:00:00.0300350 - 1.2645ms
00:00:00.0312627 - 1.2277ms
00:00:00.0325250 - 1.2623ms
00:00:00.0339893 - 1.4643ms
00:00:00.0352487 - 1.2594ms
00:00:00.0364794 - 1.2307ms
00:00:00.0377117 - 1.2323ms
00:00:00.0389332 - 1.2215ms
```

## △： Thread.Sleep with NtSetTimerResolution(0.1ms)
だいたい1.5ms以下。15msよりはマシ。
```
 ThreadSleepWithNtSetTimerResolution100us
   Source: TimerPrecisionTests.cs line 160
   Duration: 40 ms

  Standard Output: 
00:00:00.0003966 - 0ms
00:00:00.0015718 - 1.1752ms
00:00:00.0028773 - 1.3055ms
00:00:00.0040788 - 1.2015ms
00:00:00.0055790 - 1.5002ms
00:00:00.0070175 - 1.4385ms
00:00:00.0085373 - 1.5198ms
00:00:00.0099929 - 1.4556ms
00:00:00.0117467 - 1.7538ms
00:00:00.0132515 - 1.5048ms
00:00:00.0147125 - 1.461ms
00:00:00.0160025 - 1.29ms
00:00:00.0171725 - 1.17ms
00:00:00.0182847 - 1.1122ms
00:00:00.0194767 - 1.192ms
00:00:00.0208789 - 1.4022ms
00:00:00.0220121 - 1.1332ms
00:00:00.0231879 - 1.1758ms
00:00:00.0243719 - 1.184ms
00:00:00.0254578 - 1.0859ms
00:00:00.0269209 - 1.4631ms
00:00:00.0279942 - 1.0733ms
00:00:00.0294691 - 1.4749ms
00:00:00.0305547 - 1.0856ms
00:00:00.0317481 - 1.1934ms
00:00:00.0329521 - 1.204ms
00:00:00.0342207 - 1.2686ms
00:00:00.0353397 - 1.119ms
00:00:00.0364662 - 1.1265ms
00:00:00.0377456 - 1.2794ms
```

## △： timeSetEvent with timeBeginPeriod(1)
だいたい1ms。ただし８回に１回のペースで2msと0msが混じる。
```
 TimeSetEventWithTimeBeginPeriod
   Source: TimerPrecisionTests.cs line 242
   Duration: 47 ms

  Standard Output: 
00:00:00.0061221 - 0ms
00:00:00.0061293 - 0.0072ms
00:00:00.0061297 - 0.0004ms
00:00:00.0062307 - 0.101ms
00:00:00.0063983 - 0.1676ms
00:00:00.0074529 - 1.0546ms
00:00:00.0084586 - 1.0057ms
00:00:00.0094695 - 1.0109ms
00:00:00.0103678 - 0.8983ms
00:00:00.0113930 - 1.0252ms
00:00:00.0124390 - 1.046ms
00:00:00.0135535 - 1.1145ms
00:00:00.0135538 - 0.0003ms
00:00:00.0145353 - 0.9815ms
00:00:00.0166908 - 2.1555ms
00:00:00.0166912 - 0.0004ms
00:00:00.0176893 - 0.9981ms
00:00:00.0186542 - 0.9649ms
00:00:00.0197534 - 1.0992ms
00:00:00.0207387 - 0.9853ms
00:00:00.0229875 - 2.2488ms
00:00:00.0229882 - 0.0007ms
00:00:00.0239469 - 0.9587ms
00:00:00.0246771 - 0.7302ms
00:00:00.0256695 - 0.9924ms
00:00:00.0267113 - 1.0418ms
00:00:00.0276274 - 0.9161ms
00:00:00.0286545 - 1.0271ms
00:00:00.0296917 - 1.0372ms
00:00:00.0307638 - 1.0721ms
```

## 〇： timeSetEvent with NtSetTimerResolution(1ms)
だいたい1.1ms以下。
```
 TimeSetEventWithNtSetTimerResolution1000us
   Source: TimerPrecisionTests.cs line 232
   Duration: 35 ms

  Standard Output: 
00:00:00.0021211 - 0ms
00:00:00.0030227 - 0.9016ms
00:00:00.0039658 - 0.9431ms
00:00:00.0050203 - 1.0545ms
00:00:00.0060309 - 1.0106ms
00:00:00.0070995 - 1.0686ms
00:00:00.0081458 - 1.0463ms
00:00:00.0091001 - 0.9543ms
00:00:00.0100560 - 0.9559ms
00:00:00.0110250 - 0.969ms
00:00:00.0119868 - 0.9618ms
00:00:00.0129971 - 1.0103ms
00:00:00.0141254 - 1.1283ms
00:00:00.0149774 - 0.852ms
00:00:00.0160902 - 1.1128ms
00:00:00.0172458 - 1.1556ms
00:00:00.0182655 - 1.0197ms
00:00:00.0192302 - 0.9647ms
00:00:00.0201871 - 0.9569ms
00:00:00.0212254 - 1.0383ms
00:00:00.0222655 - 1.0401ms
00:00:00.0232235 - 0.958ms
00:00:00.0240828 - 0.8593ms
00:00:00.0252534 - 1.1706ms
00:00:00.0262387 - 0.9853ms
00:00:00.0269640 - 0.7253ms
00:00:00.0280398 - 1.0758ms
00:00:00.0289500 - 0.9102ms
00:00:00.0299107 - 0.9607ms
00:00:00.0309357 - 1.025ms
```

## △：timeSetEvent with NtSetTimerResolution(0.5ms)
だいたい1ms。ただし１０回に１回のペースで2msと0msが混じる。
```
 TimeSetEventWithNtSetTimerResolution500us
   Source: TimerPrecisionTests.cs line 180
   Duration: 32 ms

  Standard Output: 
00:00:00.0010981 - 0ms
00:00:00.0020619 - 0.9638ms
00:00:00.0030701 - 1.0082ms
00:00:00.0040534 - 0.9833ms
00:00:00.0050986 - 1.0452ms
00:00:00.0060443 - 0.9457ms
00:00:00.0070811 - 1.0368ms
00:00:00.0080787 - 0.9976ms
00:00:00.0090455 - 0.9668ms
00:00:00.0100755 - 1.03ms
00:00:00.0110421 - 0.9666ms
00:00:00.0130726 - 2.0305ms
00:00:00.0140838 - 1.0112ms
00:00:00.0140841 - 0.0003ms
00:00:00.0150683 - 0.9842ms
00:00:00.0160420 - 0.9737ms
00:00:00.0170565 - 1.0145ms
00:00:00.0180614 - 1.0049ms
00:00:00.0190842 - 1.0228ms
00:00:00.0200600 - 0.9758ms
00:00:00.0210406 - 0.9806ms
00:00:00.0230837 - 2.0431ms
00:00:00.0242642 - 1.1805ms
00:00:00.0242647 - 0.0005ms
00:00:00.0252559 - 0.9912ms
00:00:00.0265842 - 1.3283ms
00:00:00.0273209 - 0.7367ms
00:00:00.0282385 - 0.9176ms
00:00:00.0292902 - 1.0517ms
00:00:00.0305509 - 1.2607ms
```

## ~~〇~~ △： timeSetEvent with NtSetTimerResolution(0.1ms)
~~ほぼ1msと言ってよい。~~
だいたい1ms。ただし３０回中１回1.9msが混じる。
```
 TimeSetEventWithNtSetTimerResolution100us
   Source: TimerPrecisionTests.cs line 222
   Duration: 33 ms

  Standard Output: 
00:00:00.0010739 - 0ms
00:00:00.0020716 - 0.9977ms
00:00:00.0030730 - 1.0014ms
00:00:00.0040818 - 1.0088ms
00:00:00.0050546 - 0.9728ms
00:00:00.0060603 - 1.0057ms
00:00:00.0070420 - 0.9817ms
00:00:00.0080650 - 1.023ms
00:00:00.0090716 - 1.0066ms
00:00:00.0100556 - 0.984ms
00:00:00.0110535 - 0.9979ms
00:00:00.0120606 - 1.0071ms
00:00:00.0130475 - 0.9869ms
00:00:00.0140616 - 1.0141ms
00:00:00.0150433 - 0.9817ms
00:00:00.0170199 - 1.9766ms
00:00:00.0180128 - 0.9929ms
00:00:00.0190066 - 0.9938ms
00:00:00.0200006 - 0.994ms
00:00:00.0210025 - 1.0019ms
00:00:00.0220403 - 1.0378ms
00:00:00.0229909 - 0.9506ms
00:00:00.0239985 - 1.0076ms
00:00:00.0250050 - 1.0065ms
00:00:00.0260003 - 0.9953ms
00:00:00.0269890 - 0.9887ms
00:00:00.0279989 - 1.0099ms
00:00:00.0289961 - 0.9972ms
00:00:00.0299740 - 0.9779ms
00:00:00.0309773 - 1.0033ms
```

# テストコードの結果出力、追加分

WaitableTimer, WaitableTimeEx(CREATE_WAITABLE_TIMER_HIGH_RESOLUTIONフラグ有効)について追加で計測した。組み合わせの数が多いのでNtSetTimerResolutionは1ms設定だけ掲載。

## △： WaitableTimer(1ms).WaitOne with timeBeginPeriod(1)
だいたい2ms以下。

```
 WaitableTimerAndWaitOneWithTimeBeginPeriod(1000)
   Source: TimerPrecisionTests.cs line 258
   Duration: 58 ms

  Standard Output: 
00:00:00.0021062 - 0ms
00:00:00.0034953 - 1.3891ms
00:00:00.0051108 - 1.6155ms
00:00:00.0071326 - 2.0218ms
00:00:00.0091110 - 1.9784ms
00:00:00.0111337 - 2.0227ms
00:00:00.0131437 - 2.01ms
00:00:00.0151225 - 1.9788ms
00:00:00.0171395 - 2.017ms
00:00:00.0191230 - 1.9835ms
00:00:00.0211202 - 1.9972ms
00:00:00.0231079 - 1.9877ms
00:00:00.0251053 - 1.9974ms
00:00:00.0271024 - 1.9971ms
00:00:00.0280998 - 0.9974ms
00:00:00.0300791 - 1.9793ms
00:00:00.0320801 - 2.001ms
00:00:00.0330812 - 1.0011ms
00:00:00.0350361 - 1.9549ms
00:00:00.0370734 - 2.0373ms
00:00:00.0390784 - 2.005ms
00:00:00.0410651 - 1.9867ms
00:00:00.0429810 - 1.9159ms
00:00:00.0440159 - 1.0349ms
00:00:00.0460469 - 2.031ms
00:00:00.0480340 - 1.9871ms
00:00:00.0490012 - 0.9672ms
00:00:00.0510392 - 2.038ms
00:00:00.0530369 - 1.9977ms
00:00:00.0550372 - 2.0003ms
```

## 〇： WaitableTimer(0.5ms).WaitOne with timeBeginPeriod(1)
だいたい1ms。

```
 WaitableTimerAndWaitOneWithTimeBeginPeriod(500)
   Source: TimerPrecisionTests.cs line 258
   Duration: 31 ms

  Standard Output: 
00:00:00.0006917 - 0ms
00:00:00.0016449 - 0.9532ms
00:00:00.0027296 - 1.0847ms
00:00:00.0037397 - 1.0101ms
00:00:00.0047462 - 1.0065ms
00:00:00.0056939 - 0.9477ms
00:00:00.0067393 - 1.0454ms
00:00:00.0076886 - 0.9493ms
00:00:00.0086785 - 0.9899ms
00:00:00.0097412 - 1.0627ms
00:00:00.0107164 - 0.9752ms
00:00:00.0116782 - 0.9618ms
00:00:00.0127156 - 1.0374ms
00:00:00.0137116 - 0.996ms
00:00:00.0147173 - 1.0057ms
00:00:00.0156773 - 0.96ms
00:00:00.0167061 - 1.0288ms
00:00:00.0177017 - 0.9956ms
00:00:00.0186962 - 0.9945ms
00:00:00.0196824 - 0.9862ms
00:00:00.0207017 - 1.0193ms
00:00:00.0217288 - 1.0271ms
00:00:00.0227010 - 0.9722ms
00:00:00.0236909 - 0.9899ms
00:00:00.0246972 - 1.0063ms
00:00:00.0256221 - 0.9249ms
00:00:00.0266865 - 1.0644ms
00:00:00.0276189 - 0.9324ms
00:00:00.0286834 - 1.0645ms
00:00:00.0296208 - 0.9374ms
```

## 〇： WaitableTimer(0.1ms).WaitOne with timeBeginPeriod(1)
だいたい1ms。

```
 WaitableTimerAndWaitOneWithTimeBeginPeriod(100)
   Source: TimerPrecisionTests.cs line 258
   Duration: 31 ms

  Standard Output: 
00:00:00.0007356 - 0ms
00:00:00.0017719 - 1.0363ms
00:00:00.0027948 - 1.0229ms
00:00:00.0038504 - 1.0556ms
00:00:00.0047682 - 0.9178ms
00:00:00.0058273 - 1.0591ms
00:00:00.0067875 - 0.9602ms
00:00:00.0077236 - 0.9361ms
00:00:00.0087650 - 1.0414ms
00:00:00.0097195 - 0.9545ms
00:00:00.0107693 - 1.0498ms
00:00:00.0118201 - 1.0508ms
00:00:00.0127632 - 0.9431ms
00:00:00.0137546 - 0.9914ms
00:00:00.0147771 - 1.0225ms
00:00:00.0157601 - 0.983ms
00:00:00.0167941 - 1.034ms
00:00:00.0177569 - 0.9628ms
00:00:00.0187893 - 1.0324ms
00:00:00.0197126 - 0.9233ms
00:00:00.0206895 - 0.9769ms
00:00:00.0217027 - 1.0132ms
00:00:00.0227342 - 1.0315ms
00:00:00.0237280 - 0.9938ms
00:00:00.0247464 - 1.0184ms
00:00:00.0257257 - 0.9793ms
00:00:00.0267404 - 1.0147ms
00:00:00.0277843 - 1.0439ms
00:00:00.0286960 - 0.9117ms
00:00:00.0297156 - 1.0196ms
```

## △： WaitableTimer(1ms) with NtSetTimerResolution(1ms)
大体2ms以下。

```
 WaitableTimerAndWaitOneWithNtSetTimerResolution(10000,1000)
   Source: TimerPrecisionTests.cs line 274
   Duration: 59 ms

  Standard Output: 
00:00:00.0025242 - 0ms
00:00:00.0035436 - 1.0194ms
00:00:00.0055492 - 2.0056ms
00:00:00.0075420 - 1.9928ms
00:00:00.0085333 - 0.9913ms
00:00:00.0105572 - 2.0239ms
00:00:00.0124694 - 1.9122ms
00:00:00.0145226 - 2.0532ms
00:00:00.0165158 - 1.9932ms
00:00:00.0184756 - 1.9598ms
00:00:00.0205466 - 2.071ms
00:00:00.0224979 - 1.9513ms
00:00:00.0244622 - 1.9643ms
00:00:00.0264711 - 2.0089ms
00:00:00.0284958 - 2.0247ms
00:00:00.0304424 - 1.9466ms
00:00:00.0314810 - 1.0386ms
00:00:00.0324336 - 0.9526ms
00:00:00.0344598 - 2.0262ms
00:00:00.0364214 - 1.9616ms
00:00:00.0384501 - 2.0287ms
00:00:00.0404514 - 2.0013ms
00:00:00.0424586 - 2.0072ms
00:00:00.0444394 - 1.9808ms
00:00:00.0463670 - 1.9276ms
00:00:00.0484381 - 2.0711ms
00:00:00.0504314 - 1.9933ms
00:00:00.0524176 - 1.9862ms
00:00:00.0544078 - 1.9902ms
00:00:00.0553768 - 0.969ms
```

## 〇： WaitableTimer(0.5ms) with NtSetTimerResolution(1ms)
大体1ms.

```
 WaitableTimerAndWaitOneWithNtSetTimerResolution(10000,500)
   Source: TimerPrecisionTests.cs line 274
   Duration: 31 ms

  Standard Output: 
00:00:00.0007545 - 0ms
00:00:00.0016731 - 0.9186ms
00:00:00.0027635 - 1.0904ms
00:00:00.0037695 - 1.006ms
00:00:00.0047294 - 0.9599ms
00:00:00.0056941 - 0.9647ms
00:00:00.0067501 - 1.056ms
00:00:00.0077505 - 1.0004ms
00:00:00.0087525 - 1.002ms
00:00:00.0097522 - 0.9997ms
00:00:00.0106744 - 0.9222ms
00:00:00.0117199 - 1.0455ms
00:00:00.0126592 - 0.9393ms
00:00:00.0136635 - 1.0043ms
00:00:00.0146703 - 1.0068ms
00:00:00.0157205 - 1.0502ms
00:00:00.0166558 - 0.9353ms
00:00:00.0176794 - 1.0236ms
00:00:00.0186926 - 1.0132ms
00:00:00.0196469 - 0.9543ms
00:00:00.0206760 - 1.0291ms
00:00:00.0216459 - 0.9699ms
00:00:00.0227004 - 1.0545ms
00:00:00.0236623 - 0.9619ms
00:00:00.0246512 - 0.9889ms
00:00:00.0256304 - 0.9792ms
00:00:00.0266640 - 1.0336ms
00:00:00.0276432 - 0.9792ms
00:00:00.0286236 - 0.9804ms
00:00:00.0296390 - 1.0154ms
```

## 〇： WaitableTimer(0.1ms) with NtSetTimerResolution(1ms)
大体1ms.

```
 WaitableTimerAndWaitOneWithNtSetTimerResolution(10000,100)
   Source: TimerPrecisionTests.cs line 274
   Duration: 31 ms

  Standard Output: 
00:00:00.0007932 - 0ms
00:00:00.0018391 - 1.0459ms
00:00:00.0028442 - 1.0051ms
00:00:00.0038437 - 0.9995ms
00:00:00.0048370 - 0.9933ms
00:00:00.0058243 - 0.9873ms
00:00:00.0068338 - 1.0095ms
00:00:00.0078012 - 0.9674ms
00:00:00.0088189 - 1.0177ms
00:00:00.0098246 - 1.0057ms
00:00:00.0107837 - 0.9591ms
00:00:00.0118153 - 1.0316ms
00:00:00.0128064 - 0.9911ms
00:00:00.0138463 - 1.0399ms
00:00:00.0148293 - 0.983ms
00:00:00.0158698 - 1.0405ms
00:00:00.0167449 - 0.8751ms
00:00:00.0177982 - 1.0533ms
00:00:00.0188068 - 1.0086ms
00:00:00.0198379 - 1.0311ms
00:00:00.0208063 - 0.9684ms
00:00:00.0218348 - 1.0285ms
00:00:00.0227855 - 0.9507ms
00:00:00.0238326 - 1.0471ms
00:00:00.0247933 - 0.9607ms
00:00:00.0258321 - 1.0388ms
00:00:00.0268025 - 0.9704ms
00:00:00.0278026 - 1.0001ms
00:00:00.0287881 - 0.9855ms
00:00:00.0294104 - 0.6223ms
```

## △： WaitableTimerEx(1ms) with NtSetTimerResolution(1ms)
大体2ms以下。

```
 WaitableTimerHighResolutionAndWaitOneWithTimeBeginPeriod(1000)
   Source: TimerPrecisionTests.cs line 321
   Duration: 56 ms

  Standard Output: 
00:00:00.0018973 - 0ms
00:00:00.0032925 - 1.3952ms
00:00:00.0052534 - 1.9609ms
00:00:00.0067099 - 1.4565ms
00:00:00.0084615 - 1.7516ms
00:00:00.0104547 - 1.9932ms
00:00:00.0115111 - 1.0564ms
00:00:00.0135211 - 2.01ms
00:00:00.0150632 - 1.5421ms
00:00:00.0172808 - 2.2176ms
00:00:00.0192905 - 2.0097ms
00:00:00.0210495 - 1.759ms
00:00:00.0230367 - 1.9872ms
00:00:00.0250651 - 2.0284ms
00:00:00.0261239 - 1.0588ms
00:00:00.0281704 - 2.0465ms
00:00:00.0292853 - 1.1149ms
00:00:00.0303221 - 1.0368ms
00:00:00.0323046 - 1.9825ms
00:00:00.0343565 - 2.0519ms
00:00:00.0364315 - 2.075ms
00:00:00.0384010 - 1.9695ms
00:00:00.0403957 - 1.9947ms
00:00:00.0424832 - 2.0875ms
00:00:00.0440263 - 1.5431ms
00:00:00.0451157 - 1.0894ms
00:00:00.0470917 - 1.976ms
00:00:00.0489886 - 1.8969ms
00:00:00.0504352 - 1.4466ms
00:00:00.0525067 - 2.0715ms
```

## 〇： WaitableTimerEx(0.5ms) with NtSetTimerResolution(1ms)
1ms以下。0.53～0.78msの範囲内。最初はブレがおおきい？実装の問題かも。

```
 WaitableTimerHighResolutionAndWaitOneWithTimeBeginPeriod(500)
   Source: TimerPrecisionTests.cs line 321
   Duration: 20 ms

  Standard Output: 
00:00:00.0016733 - 0ms
00:00:00.0026283 - 0.955ms
00:00:00.0032136 - 0.5853ms
00:00:00.0037770 - 0.5634ms
00:00:00.0043553 - 0.5783ms
00:00:00.0049102 - 0.5549ms
00:00:00.0054467 - 0.5365ms
00:00:00.0060186 - 0.5719ms
00:00:00.0065325 - 0.5139ms
00:00:00.0070883 - 0.5558ms
00:00:00.0076849 - 0.5966ms
00:00:00.0082427 - 0.5578ms
00:00:00.0088143 - 0.5716ms
00:00:00.0094430 - 0.6287ms
00:00:00.0100123 - 0.5693ms
00:00:00.0105676 - 0.5553ms
00:00:00.0111468 - 0.5792ms
00:00:00.0117676 - 0.6208ms
00:00:00.0123191 - 0.5515ms
00:00:00.0129283 - 0.6092ms
00:00:00.0135489 - 0.6206ms
00:00:00.0142670 - 0.7181ms
00:00:00.0149061 - 0.6391ms
00:00:00.0156873 - 0.7812ms
00:00:00.0163473 - 0.66ms
00:00:00.0170874 - 0.7401ms
00:00:00.0177504 - 0.663ms
00:00:00.0183230 - 0.5726ms
00:00:00.0189433 - 0.6203ms
00:00:00.0195083 - 0.565ms
```

## 〇： WaitableTimerEx(0.1ms) with NtSetTimerResolution(1ms)
1ms以下。だいたいは0.50～0.74msの範囲内だが、6回に１回の頻度で0.18ms, 0.07ms, 0.27msなど短めのものが混じる。

```
 WaitableTimerHighResolutionAndWaitOneWithTimeBeginPeriod(100)
   Source: TimerPrecisionTests.cs line 321
   Duration: 17 ms

  Standard Output: 
00:00:00.0010502 - 0ms
00:00:00.0015877 - 0.5375ms
00:00:00.0021134 - 0.5257ms
00:00:00.0026761 - 0.5627ms
00:00:00.0032907 - 0.6146ms
00:00:00.0037994 - 0.5087ms
00:00:00.0043484 - 0.549ms
00:00:00.0049059 - 0.5575ms
00:00:00.0054704 - 0.5645ms
00:00:00.0060477 - 0.5773ms
00:00:00.0066413 - 0.5936ms
00:00:00.0072322 - 0.5909ms
00:00:00.0074212 - 0.189ms
00:00:00.0081047 - 0.6835ms
00:00:00.0086645 - 0.5598ms
00:00:00.0092820 - 0.6175ms
00:00:00.0093744 - 0.0924ms
00:00:00.0100250 - 0.6506ms
00:00:00.0106953 - 0.6703ms
00:00:00.0107879 - 0.0926ms
00:00:00.0113827 - 0.5948ms
00:00:00.0119836 - 0.6009ms
00:00:00.0127251 - 0.7415ms
00:00:00.0133412 - 0.6161ms
00:00:00.0134176 - 0.0764ms
00:00:00.0140254 - 0.6078ms
00:00:00.0145923 - 0.5669ms
00:00:00.0148661 - 0.2738ms
00:00:00.0154604 - 0.5943ms
00:00:00.0159875 - 0.5271ms
```

## ×： WaitableTimerEx(1ms), 解像度変更なし
15ms.

```
 WaitableTimerAndWaitOneSingle(1000)
   Source: TimerPrecisionTests.cs line 351
   Duration: 505 ms

  Standard Output: 
00:00:00.0205120 - 0ms
00:00:00.0335582 - 13.0462ms
00:00:00.0489147 - 15.3565ms
00:00:00.0641700 - 15.2553ms
00:00:00.0796497 - 15.4797ms
00:00:00.0948636 - 15.2139ms
00:00:00.1107037 - 15.8401ms
00:00:00.1259992 - 15.2955ms
00:00:00.1412250 - 15.2258ms
00:00:00.1569929 - 15.7679ms
00:00:00.1724665 - 15.4736ms
00:00:00.1879815 - 15.515ms
00:00:00.2034383 - 15.4568ms
00:00:00.2188739 - 15.4356ms
00:00:00.2340104 - 15.1365ms
00:00:00.2494744 - 15.464ms
00:00:00.2652279 - 15.7535ms
00:00:00.2808313 - 15.6034ms
00:00:00.2965209 - 15.6896ms
00:00:00.3118770 - 15.3561ms
00:00:00.3266501 - 14.7731ms
00:00:00.3426223 - 15.9722ms
00:00:00.3578510 - 15.2287ms
00:00:00.3733334 - 15.4824ms
00:00:00.3890310 - 15.6976ms
00:00:00.4044010 - 15.37ms
00:00:00.4198384 - 15.4374ms
00:00:00.4359565 - 16.1181ms
00:00:00.4514387 - 15.4822ms
00:00:00.4667070 - 15.2683ms
```

## ×： WaitableTimerEx(0.5ms), 解像度変更なし
15ms.

```
 WaitableTimerAndWaitOneSingle(500)
   Source: TimerPrecisionTests.cs line 351
   Duration: 473 ms

  Standard Output: 
00:00:00.0090604 - 0ms
00:00:00.0239812 - 14.9208ms
00:00:00.0399537 - 15.9725ms
00:00:00.0554679 - 15.5142ms
00:00:00.0707849 - 15.317ms
00:00:00.0856701 - 14.8852ms
00:00:00.1008905 - 15.2204ms
00:00:00.1167330 - 15.8425ms
00:00:00.1318964 - 15.1634ms
00:00:00.1471143 - 15.2179ms
00:00:00.1623606 - 15.2463ms
00:00:00.1778096 - 15.449ms
00:00:00.1930692 - 15.2596ms
00:00:00.2085001 - 15.4309ms
00:00:00.2243864 - 15.8863ms
00:00:00.2397071 - 15.3207ms
00:00:00.2546997 - 14.9926ms
00:00:00.2705458 - 15.8461ms
00:00:00.2855747 - 15.0289ms
00:00:00.3033628 - 17.7881ms
00:00:00.3164407 - 13.0779ms
00:00:00.3314322 - 14.9915ms
00:00:00.3473785 - 15.9463ms
00:00:00.3625654 - 15.1869ms
00:00:00.3785857 - 16.0203ms
00:00:00.3943015 - 15.7158ms
00:00:00.4099544 - 15.6529ms
00:00:00.4252214 - 15.267ms
00:00:00.4409872 - 15.7658ms
00:00:00.4565003 - 15.5131ms
```

## ×： WaitableTimerEx(0.1ms), 解像度変更なし
15ms.

```
 WaitableTimerAndWaitOneSingle(100)
   Source: TimerPrecisionTests.cs line 351
   Duration: 472 ms

  Standard Output: 
00:00:00.0149453 - 0ms
00:00:00.0299797 - 15.0344ms
00:00:00.0450342 - 15.0545ms
00:00:00.0600952 - 15.061ms
00:00:00.0758562 - 15.761ms
00:00:00.0915618 - 15.7056ms
00:00:00.1071724 - 15.6106ms
00:00:00.1226075 - 15.4351ms
00:00:00.1377612 - 15.1537ms
00:00:00.1534752 - 15.714ms
00:00:00.1684472 - 14.972ms
00:00:00.1841736 - 15.7264ms
00:00:00.1990171 - 14.8435ms
00:00:00.2139156 - 14.8985ms
00:00:00.2299023 - 15.9867ms
00:00:00.2452771 - 15.3748ms
00:00:00.2604999 - 15.2228ms
00:00:00.2757197 - 15.2198ms
00:00:00.2904187 - 14.699ms
00:00:00.3056912 - 15.2725ms
00:00:00.3209609 - 15.2697ms
00:00:00.3365054 - 15.5445ms
00:00:00.3516700 - 15.1646ms
00:00:00.3670849 - 15.4149ms
00:00:00.3821572 - 15.0723ms
00:00:00.3971286 - 14.9714ms
00:00:00.4121431 - 15.0145ms
00:00:00.4269074 - 14.7643ms
00:00:00.4420751 - 15.1677ms
00:00:00.4568275 - 14.7524ms
```

## 〇： WaitableTimerEx(0.5ms) with NtSetTimerResolution(100ms)
だいたい1ms以下。30回中に4回0.97ms越え、他はだいたい0.5～0.66msの範囲内だが、最初のほうで0.0001msで返っている。

```
 WaitableTimerHighResolutionAndWaitOne500usWithTimeBeginPeriod(100)
   Source: TimerPrecisionTests.cs line 361
   Duration: 41 ms

  Standard Output: 
00:00:00.0098812 - 0ms
00:00:00.0098849 - 0.0037ms
00:00:00.0099720 - 0.0871ms
00:00:00.0099721 - 0.0001ms
00:00:00.0104799 - 0.5078ms
00:00:00.0115102 - 1.0303ms
00:00:00.0120849 - 0.5747ms
00:00:00.0125952 - 0.5103ms
00:00:00.0136476 - 1.0524ms
00:00:00.0143037 - 0.6561ms
00:00:00.0148359 - 0.5322ms
00:00:00.0154912 - 0.6553ms
00:00:00.0160562 - 0.565ms
00:00:00.0165877 - 0.5315ms
00:00:00.0171240 - 0.5363ms
00:00:00.0177138 - 0.5898ms
00:00:00.0182615 - 0.5477ms
00:00:00.0189352 - 0.6737ms
00:00:00.0195011 - 0.5659ms
00:00:00.0201619 - 0.6608ms
00:00:00.0207160 - 0.5541ms
00:00:00.0213258 - 0.6098ms
00:00:00.0223866 - 1.0608ms
00:00:00.0230000 - 0.6134ms
00:00:00.0239757 - 0.9757ms
00:00:00.0246114 - 0.6357ms
00:00:00.0251349 - 0.5235ms
00:00:00.0257134 - 0.5785ms
00:00:00.0262734 - 0.56ms
00:00:00.0268896 - 0.6162ms
```

## 〇： WaitableTimerEx(0.5ms) with NtSetTimerResolution(15ms)
だいたい1ms以下。30回中に5回1ms越え、0.87ms, 0.94msもちらほら。他はだいたい0.5～0.66msの範囲内。最初の方も安定している。

```
 WaitableTimerHighResolutionAndWaitOne500usWithTimeBeginPeriod(15)
   Source: TimerPrecisionTests.cs line 361
   Duration: 22 ms

  Standard Output: 
00:00:00.0012504 - 0ms
00:00:00.0018446 - 0.5942ms
00:00:00.0024614 - 0.6168ms
00:00:00.0031276 - 0.6662ms
00:00:00.0036947 - 0.5671ms
00:00:00.0043391 - 0.6444ms
00:00:00.0048793 - 0.5402ms
00:00:00.0055338 - 0.6545ms
00:00:00.0060909 - 0.5571ms
00:00:00.0067198 - 0.6289ms
00:00:00.0072849 - 0.5651ms
00:00:00.0078487 - 0.5638ms
00:00:00.0083489 - 0.5002ms
00:00:00.0094134 - 1.0645ms
00:00:00.0104249 - 1.0115ms
00:00:00.0114989 - 1.074ms
00:00:00.0124437 - 0.9448ms
00:00:00.0134715 - 1.0278ms
00:00:00.0141508 - 0.6793ms
00:00:00.0148857 - 0.7349ms
00:00:00.0157627 - 0.877ms
00:00:00.0163634 - 0.6007ms
00:00:00.0169334 - 0.57ms
00:00:00.0174439 - 0.5105ms
00:00:00.0179764 - 0.5325ms
00:00:00.0186337 - 0.6573ms
00:00:00.0196995 - 1.0658ms
00:00:00.0202584 - 0.5589ms
00:00:00.0207947 - 0.5363ms
00:00:00.0213413 - 0.5466ms
```

## △： WaitableTimerEx(0.5ms) with NtSetTimerResolution(10ms)
だいたい1ms以下だが、１回5.7msが出ている。たまたまマシンが重かった可能性もある。

```
 WaitableTimerHighResolutionAndWaitOne500usWithTimeBeginPeriod(10)
   Source: TimerPrecisionTests.cs line 361
   Duration: 26 ms

  Standard Output: 
00:00:00.0010283 - 0ms
00:00:00.0016217 - 0.5934ms
00:00:00.0022386 - 0.6169ms
00:00:00.0028728 - 0.6342ms
00:00:00.0034471 - 0.5743ms
00:00:00.0040700 - 0.6229ms
00:00:00.0047513 - 0.6813ms
00:00:00.0053432 - 0.5919ms
00:00:00.0058763 - 0.5331ms
00:00:00.0064643 - 0.588ms
00:00:00.0122287 - 5.7644ms
00:00:00.0128198 - 0.5911ms
00:00:00.0133836 - 0.5638ms
00:00:00.0139166 - 0.533ms
00:00:00.0145282 - 0.6116ms
00:00:00.0151469 - 0.6187ms
00:00:00.0158266 - 0.6797ms
00:00:00.0164495 - 0.6229ms
00:00:00.0171274 - 0.6779ms
00:00:00.0181563 - 1.0289ms
00:00:00.0188149 - 0.6586ms
00:00:00.0194051 - 0.5902ms
00:00:00.0199053 - 0.5002ms
00:00:00.0205418 - 0.6365ms
00:00:00.0211769 - 0.6351ms
00:00:00.0218759 - 0.699ms
00:00:00.0224450 - 0.5691ms
00:00:00.0230010 - 0.556ms
00:00:00.0241397 - 1.1387ms
00:00:00.0248117 - 0.672ms
```

## △： WaitableTimerEx(0.5ms) with NtSetTimerResolution(5ms)
だいたい1ms以下。30回中２回1ms越え。他は0.46～0.67msの範囲内。

```
 WaitableTimerHighResolutionAndWaitOne500usWithTimeBeginPeriod(5)
   Source: TimerPrecisionTests.cs line 361
   Duration: 20 ms

  Standard Output: 
00:00:00.0009330 - 0ms
00:00:00.0014650 - 0.532ms
00:00:00.0025316 - 1.0666ms
00:00:00.0035330 - 1.0014ms
00:00:00.0041941 - 0.6611ms
00:00:00.0047518 - 0.5577ms
00:00:00.0054184 - 0.6666ms
00:00:00.0059785 - 0.5601ms
00:00:00.0066183 - 0.6398ms
00:00:00.0071769 - 0.5586ms
00:00:00.0077591 - 0.5822ms
00:00:00.0083152 - 0.5561ms
00:00:00.0088575 - 0.5423ms
00:00:00.0094337 - 0.5762ms
00:00:00.0099943 - 0.5606ms
00:00:00.0105427 - 0.5484ms
00:00:00.0111406 - 0.5979ms
00:00:00.0116862 - 0.5456ms
00:00:00.0122342 - 0.548ms
00:00:00.0128133 - 0.5791ms
00:00:00.0133637 - 0.5504ms
00:00:00.0139862 - 0.6225ms
00:00:00.0146440 - 0.6578ms
00:00:00.0151082 - 0.4642ms
00:00:00.0157726 - 0.6644ms
00:00:00.0163878 - 0.6152ms
00:00:00.0170655 - 0.6777ms
00:00:00.0176865 - 0.621ms
00:00:00.0183384 - 0.6519ms
00:00:00.0189285 - 0.5901ms
```

# 実験後のまとめ（初回テスト時）

## 1msタイマー

timeSetEventとNtSetTimerResolution(1ms) の組み合わせでだいたい1msのタイマーが使える。

※timeSetEventを使うにはtimeBeginPeriodの呼び出しもあわせて要るので忘れないこと。

## 2msタイマー

timeSetEventはタイマーID管理の手間がかかる。もし必要タイマー数が１つ程度で最小時間2msが許容できるなら Thread.Sleep(1) & timeBeginPeriod(1) の組み合わせもありだと思う。

MonoGameでは睡眠予定時間が2ms以上の場合のみThread.Sleep(1)するコードも見かけた。

https://github.com/MonoGame/MonoGame/blob/225045b3f1579078757a1a63002d764a87e04fa8/MonoGame.Framework/Game.cs#L559

## 実験後のまとめ（追加テスト後）

WaitableTimerExとCREATE_WAITABLE_TIMER_HIGH_RESOLUTIONフラグ、timeBeginPeriodの組み合わせを使うと0.7ms前後で時間待ちできることがわかった。

不思議な挙動としてtimeBeginPeriodを呼ばないと15msになり、呼びさえすれば15ms刻み設定であっても効果がある。呼ぶこと自体になにかのフラグ操作の効果がありそう。

初回テスト時はタイマーが２倍の範囲内でぶれることから標本化定理的なものを感じていて、低負荷なテスト時にだいたい1msであってもちょっと負荷がかかったらいきなり2msになるのでは？と不安を感じていた。今回のタイマー解像度を無視するらしき方法を使えば1msから2msに飛ぶ可能性がすこし減らせるかもしれない。

# ※参考資料

## timeSetEvent

https://stackoverflow.com/questions/9228313/most-accurate-timer-in-net

timeSetEventをC#から使うコードが掲載されている。

https://www.ipentec.com/document/csharp-create-timer-using-timesetevent

timeSetEventをC#から使うコードが掲載されている。

https://learn.microsoft.com/ja-jp/previous-versions//dd757634(v=vs.85)

timeSetEventの引数の意味が書かれている。

https://bravo.tank.jp/cgi/PT.php?VCPP/API/timeSetEvent

timeSetEventの前にtimeBeginPeriodを呼ばないとだめだよと注意文が書かれている。

http://www.eternalwindows.jp/winmm/midi/midi11.html

timeSetEventの使い方 ~~や、そのコールバック中で呼び出してはいけない関数の注意文~~ が書かれている。

訂正： こちらはコールバック中で呼び出してよい関数が正しそうです。ページ全体の流れは呼び出しOKなので１か所誤字があるのかなと思いますが、閲覧の際はそこだけご注意ください。全体的には読ませていただいて助かった記事です。

→呼び出しOK関数が記載されている公式リファレンス： 
　[TimerProc callback function (Windows) | Microsoft Learn](https://learn.microsoft.com/ja-jp/previous-versions/dd757631(v=vs.85))
　　→コメントでご紹介いただきました。ありがとうございます。

https://blog.kaorun55.com/entry/20081215/1229346934

10msタイマーの作成のためにtimeSetEventで9.3ms待機、ビジーループで2us差まで追い込む方法が紹介されている。

## NtSetTimerResolution

https://misakichi-k.hatenablog.com/entry/2018/10/19/010134

NTSetTimerResolutionが紹介されている。

https://www.vbforums.com/showthread.php?703323-RESOLVED-set-windows-timer-resolution

NTSetTimerResolutionをC#から使うコードが掲載されている。

## WaitableTimer

https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw/11470617

CreateWitableTimer, SetWaitableTimerを使ったusleepに実装例が載っている。

マイクロソフト公式サイトのAPIリファレンス

→関数名や定数名、引数名で検索するとマイクロソフト公式サイトのリファレンスが出てくる。たくさん見た。

https://stackoverflow.com/questions/15858751/analog-to-waitable-timers-in-net

テストコードでもそのまま参考にさせてもらっているWaitableTimerクラス(C#)が載っている。

https://stackoverflow.com/questions/45991276/how-do-i-await-a-handle-safehandle

SafeWaitHandleとWaitHandleの変換方法が載っている。

https://s5suzuki.github.io/posts/cpp-timer/

WaitableTimerの利用コード例（C++）が載っている。

https://forums.codeguru.com/showthread.php?467183-SetWaitableTimer-confusions

bManualReset の開設が参考になった。

https://s5suzuki.github.io/posts/cpp-timer/

Windowsは0.5ms (=500us)が限界らしい。

## CREATE_WAITABLE_TIMER_HIGH_RESOLUTION

https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createwaitabletimerexw

マイクロソフト公式リファレンス。ここ以外にもたくさん見た。CREATE_WAITABLE_TIMER_HIGH_RESOLUTIONは `This value is supported in Windows 10, version 1803, and later. ` とのこと。

https://stackoverflow.com/questions/73647588/createwaitabletimerex-and-setwaitabletimerex-with-high-resolution-flag-name-and

CREATE_WAITABLE_TIMER_HIGH_RESOLUTIONの利用コード例（C++)が載っている。

https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Runtime/r3/win/timer-win.cpp#L312

CREATE_WAITABLE_TIMER_HIGH_RESOLUTIONの利用コード例（C++)が載っている。古いWindowsだとエラーが返るうんぬんのコメントもある。

## ThreadPool.RegisterWaitForSingleObject

これも試したが使用前後で特に変化がなかったため計測結果を掲載しなかった。自分でスレッドを起動せずにすむのは楽かもしれない。

https://learn.microsoft.com/en-us/dotnet/api/system.threading.threadpool.registerwaitforsingleobject?view=net-8.0

マイクロソフト公式リファレンス。ここ以外にもたくさん見た。

https://thomaslevesque.com/2015/06/04/async-and-cancellation-support-for-wait-handles/

コード例が載っている。

https://stackoverflow.com/questions/37499541/does-threadpool-registerwaitforsingleobject-block-the-current-thread-or-a-thread

コード例が載っている。