🔖
Task.Delayの精度
dotnet --version
6.0.201
Task.Delayの精度は実行する環境によって違いがあります。
ドキュメントに以下のような記載があります。
このメソッドは、システム クロックによって異なります。 つまり、引数がシステム クロックの解像度 (Windows システムでは約 15 ミリ秒) 未満の場合、遅延時間はシステム クロックの解像度 millisecondsDelay にほぼ等しくなります。
実際に以下のプログラムをWindowsとLinuxの2つの環境で実行してみます。
using System.Runtime.InteropServices;
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
var dict = new Dictionary<string, int>();
while (stopwatch.Elapsed < TimeSpan.FromMilliseconds(100))
{
var key = DateTime.UtcNow.ToString("HH:mm:ss.fff");
if (!dict.ContainsKey(key))
{
dict[key] = 0;
}
dict[key] += 1;
await Task.Delay(1);
}
foreach(var kvp in dict)
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
Console.WriteLine(dict.Count);
Console.WriteLine("Frequency = {0}", System.Diagnostics.Stopwatch.Frequency);
Windows
環境
> ver
Microsoft Windows [Version 10.0.22000.556]
結果
Key = 00:50:40.501, Value = 1
Key = 00:50:40.527, Value = 1
Key = 00:50:40.541, Value = 1
Key = 00:50:40.556, Value = 1
Key = 00:50:40.572, Value = 1
Key = 00:50:40.588, Value = 1
6
Frequency = 10000000
Linux
環境
$ cat /etc/debian_version
11.2
結果
Key = 00:39:41.117, Value = 1
Key = 00:39:41.129, Value = 1
Key = 00:39:41.131, Value = 1
Key = 00:39:41.134, Value = 1
Key = 00:39:41.139, Value = 1
Key = 00:39:41.143, Value = 1
Key = 00:39:41.146, Value = 1
Key = 00:39:41.151, Value = 1
Key = 00:39:41.155, Value = 1
Key = 00:39:41.158, Value = 1
Key = 00:39:41.163, Value = 1
Key = 00:39:41.167, Value = 1
Key = 00:39:41.170, Value = 1
Key = 00:39:41.175, Value = 1
Key = 00:39:41.178, Value = 1
Key = 00:39:41.183, Value = 1
Key = 00:39:41.187, Value = 1
Key = 00:39:41.191, Value = 1
Key = 00:39:41.195, Value = 1
Key = 00:39:41.198, Value = 1
Key = 00:39:41.203, Value = 1
Key = 00:39:41.206, Value = 1
Key = 00:39:41.211, Value = 1
Key = 00:39:41.215, Value = 1
24
Frequency = 1000000000
Task.Delayの他にもシステムクロックの解像度によって
精度が変わるメソッドがあるので、
時間に関連する処理を書くときはドキュメントを確認するようにしましょう。
Discussion