<PackageReference Include="NUnit" Version="3.10.1" />

SpinWait

public struct SpinWait
Provides support for spin-based waiting.
using System.Security.Permissions; namespace System.Threading { [HostProtection(SecurityAction.LinkDemand)] public struct SpinWait { internal const int YIELD_THRESHOLD = 10; internal const int SLEEP_0_EVERY_HOW_MANY_TIMES = 5; internal const int SLEEP_1_EVERY_HOW_MANY_TIMES = 20; private int m_count; public int Count => m_count; public bool NextSpinWillYield { get { if (m_count <= 10) return PlatformHelper.IsSingleProcessor; return true; } } public void SpinOnce() { if (NextSpinWillYield) { if (((m_count >= 10) ? (m_count - 10) : m_count) % 20 == 19) Thread.Sleep(1); else Thread.Sleep(0); } else Thread.SpinWait(4 << m_count); m_count = ((m_count == 2147483647) ? 10 : (m_count + 1)); } public void Reset() { m_count = 0; } public static void SpinUntil(Func<bool> condition) { SpinUntil(condition, -1); } public static bool SpinUntil(Func<bool> condition, TimeSpan timeout) { long num = (long)timeout.TotalMilliseconds; if (num < -1 || num > 2147483647) throw new ArgumentOutOfRangeException("timeout", timeout, "SpinWait SpinUntil Timeout Wrong"); return SpinUntil(condition, (int)timeout.TotalMilliseconds); } public static bool SpinUntil(Func<bool> condition, int millisecondsTimeout) { if (millisecondsTimeout < -1) throw new ArgumentOutOfRangeException("millisecondsTimeout"); if (condition == null) throw new ArgumentNullException("condition"); uint num = 0; if (millisecondsTimeout != 0 && millisecondsTimeout != -1) num = System.Threading.TimeoutHelper.GetTime(); SpinWait spinWait = default(SpinWait); while (!condition()) { if (millisecondsTimeout == 0) return false; spinWait.SpinOnce(); if (millisecondsTimeout != -1 && spinWait.NextSpinWillYield && millisecondsTimeout <= System.Threading.TimeoutHelper.GetTime() - num) return false; } return true; } } }