语言

SpinWait 结构

定义

提供对基于旋转的等待的支持。

public value class SpinWait
public struct SpinWait
type SpinWait = struct
Public Structure SpinWait
继承
SpinWait

示例

以下示例演示如何使用SpinWait:

using System;
using System.Threading;
using System.Threading.Tasks;

class SpinWaitDemo
{
    // Demonstrates:
    //      SpinWait construction
    //      SpinWait.SpinOnce()
    //      SpinWait.NextSpinWillYield
    //      SpinWait.Count
    static void Main()
    {
        bool someBoolean = false;
        int numYields = 0;

        // First task: SpinWait until someBoolean is set to true
        Task t1 = Task.Factory.StartNew(() =>
        {
            SpinWait sw = new SpinWait();
            while (!someBoolean)
            {
                // The NextSpinWillYield property returns true if
                // calling sw.SpinOnce() will result in yielding the
                // processor instead of simply spinning.
                if (sw.NextSpinWillYield) numYields++;
                sw.SpinOnce();
            }

            // As of .NET Framework 4: After some initial spinning, SpinWait.SpinOnce() will yield every time.
            Console.WriteLine("SpinWait called {0} times, yielded {1} times", sw.Count, numYields);
        });

        // Second task: Wait 100ms, then set someBoolean to true
        Task t2 = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(100);
            someBoolean = true;
        });

        // Wait for tasks to complete
        Task.WaitAll(t1, t2);
    }
}
Imports System.Threading
Imports System.Threading.Tasks

Module SpinWaitDemo
    ' Demonstrates:
    ' SpinWait construction
    ' SpinWait.SpinOnce()
    ' SpinWait.NextSpinWillYield
    ' SpinWait.Count
    Private Sub SpinWaitSample()
        Dim someBoolean As Boolean = False
        Dim numYields As Integer = 0

        ' First task: SpinWait until someBoolean is set to true
        Dim t1 As Task = Task.Factory.StartNew(
            Sub()
                Dim sw As New SpinWait()
                While Not someBoolean
                    ' The NextSpinWillYield property returns true if
                    ' calling sw.SpinOnce() will result in yielding the
                    ' processor instead of simply spinning.
                    If sw.NextSpinWillYield Then
                        numYields += 1
                    End If
                    sw.SpinOnce()
                End While

                ' As of .NET Framework 4: After some initial spinning, SpinWait.SpinOnce() will yield every time.
                Console.WriteLine("SpinWait called {0} times, yielded {1} times", sw.Count, numYields)
            End Sub)

        ' Second task: Wait 100ms, then set someBoolean to true
        Dim t2 As Task = Task.Factory.StartNew(
            Sub()
                Thread.Sleep(100)
                someBoolean = True
            End Sub)

        ' Wait for tasks to complete
        Task.WaitAll(t1, t2)
    End Sub

End Module

注解

SpinWait 封装常见的旋转逻辑。 在单处理器计算机上,生成始终使用,而不是忙于等待,在采用 Hyper-Threading 技术的 Intel 处理器的计算机上,这有助于防止硬件线程饥饿。 SpinWait 封装了旋转和真正的产量的良好混合物。

SpinWait 是一种值类型,这意味着低级别代码可以利用 SpinWait,而不必担心不必要的分配开销。 SpinWait 通常不适用于普通应用程序。 在大多数情况下,应使用 .NET Framework 提供的同步类,例如 Monitor。 但是,对于需要旋转等待的大多数用途, SpinWait 类型应优先于 Thread.SpinWait 该方法。

属性

名称 说明
Count

获取在此实例上调用的次数 SpinOnce() 。

NextSpinWillYield

获取下一次调用 SpinOnce() 是否会生成处理器,从而触发强制上下文切换。

方法

名称 说明
Reset()

重置旋转计数器。

SpinOnce()

执行单个旋转。

SpinOnce(Int32)

在最小旋转计数后执行单个旋转和调用 Sleep(Int32) 。

SpinUntil(Func<Boolean>, Int32)

旋转直到满足指定的条件或指定的超时过期为止。

SpinUntil(Func<Boolean>, TimeSpan)

旋转直到满足指定的条件或指定的超时过期为止。

SpinUntil(Func<Boolean>)

在满足指定条件之前旋转。

适用于

线程安全性

虽然 SpinWait 设计为在并发应用程序中使用,但它不设计为从多个线程并发使用。 SpinWait 成员不是线程安全的。 如果多个线程必须旋转,则每个线程都应使用其自己的实例 SpinWait。

另请参阅