使用 ManualResetEventSlim 而不是 ManualResetEvent 的最短等待时间是多少?

What is the minimum wait time to use ManualResetEventSlim instead of ManualResetEvent?

从 NET 4 开始,我可以使用 ManualResetEventSlim class 在阻塞之前稍微旋转一下,以便在阻塞时间很短的情况下获得时间优化(我没有上下文切换)。

我想使用基准来衡量这次时间有多短,以便或多或少地知道更喜欢使用 ManualResetEventSlim 而不是 [=36= 所需的等待时间]ic ManualResetEvent.

我知道这个度量是 CPU 相关的,不可能先验地知道旋转时间,但我想要一个数量级。

我写了一个基准测试 class 以获得使 ManualResetEventSlim 优于 ManualResetEvent 的最小 MillisecondSleep。

public class ManualResetEventTest
{
    [Params(0, 1, 10)]
    public int MillisecondsSleep;

    [Benchmark]
    public void ManualResetEventSlim()
    {
        using var mres = new ManualResetEventSlim(false);
        var t = Task.Run(() =>
        {
            mres.Wait();
        });

        Thread.Sleep(MillisecondsSleep);
        mres.Set();
        t.Wait();
    }
    
    [Benchmark]
    public void ManualResetEvent()
    {
        using var mres = new ManualResetEvent(false);
        var t = Task.Run(() =>
        {
            mres.WaitOne();
        });

        Thread.Sleep(MillisecondsSleep);
        mres.Set();
        t.Wait();
    }
}

结果如下

如您所见,我发现仅使用 Thread.Sleep(0) 即可提高性能。此外,我看到 1 毫秒和 10 毫秒的平均时间均为 15 毫秒。 我错过了什么吗?

真的只有 0 毫秒等待才更好地使用 ManualResetEventSlim 而不是 ManualResetEvent 吗?

来自优秀的 C# 9.0 in a Nutshell 书中:

Waiting or signaling an AutoResetEvent or ManualResetEvent takes about one microsecond (assuming no blocking).

ManualResetEventSlim and CountdownEvent can be up to 50 times faster in short-wait scenarios because of their nonreliance on the OS and judicious use of spinning constructs. In most scenarios, however, the overhead of the signaling classes themselves doesn't create a bottleneck; thus, it is rarely a consideration.

希望这足以给你一个粗略的数量级。