除了常見的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.jpg
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
}

創作者介紹
創作者 GNAySolution 的頭像
Yang

GNAySolution

Yang 發表在 痞客邦 留言(0) 人氣( 2 )