除了常見的for/while loop,C#還有SpinUntil可用,
效能較差,但幾乎不吃CPU資源,紀錄在此
原始碼:
DateTime dt1 = DateTime.Now.AddSeconds(60);
int cnt1 = 0;
while (DateTime.Now < dt1)
{
++cnt1;
}
Console.WriteLine($"{nameof(cnt1)}={cnt1}\n");
long dt2 = DateTime.Now.AddSeconds(60).Ticks;
int cnt2 = 0;
while (DateTime.Now.Ticks < dt2)
{
++cnt2;
}
Console.WriteLine($"{nameof(cnt2)}={cnt2}\n");
int cnt3 = 0;
bool spinResult = SpinWait.SpinUntil(() => ++cnt3 < 0, 1000 * 60);
Console.WriteLine($"{nameof(cnt3)}={cnt3}");
Console.WriteLine($"{nameof(spinResult)}={spinResult}");
測試結果:
SpinUntil比while慢超過10000倍,但while會消耗CPU接近100%,SpinUntil則是接近0%,
使用NET7,跨平臺在Win10/CentOS7測試結果類似
20230515補充:
public static bool SpinUntil (Func<bool> condition, int millisecondsTimeout);
condition回傳false代表繼續迴圈,true代表結束,
上面的++cnt3 < 0,就是回傳false(除非測太久,int爆掉),代表繼續
寫成以下程式碼,幫助記憶
public class SpinCondition
{
public const bool Continue = false;
public const bool Break = true;
}
SpinUntil如果timeout,會回傳false,
condition如果正常結束(return SpinCondition.Break),SpinUntil會回傳true
寫成以下程式碼,幫助記憶
public class SpinResult
{
public const bool Timeout = false;
public const bool Satisfied = true; //SpinCondition.Break
}