Compartilhar via


SpinWait Estrutura

Definição

Fornece suporte à espera baseada em rotação.

public value class SpinWait
public struct SpinWait
type SpinWait = struct
Public Structure SpinWait
Herança
SpinWait

Exemplos

O exemplo a seguir mostra como usar um 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

Comentários

SpinWait encapsula a lógica de rotação comum. Em computadores de processador único, os rendimentos são sempre usados em vez de esperas ocupadas e em computadores com processadores Intel que empregam Hyper-Threading tecnologia, isso ajuda a evitar a fome de threads de hardware. SpinWait encapsula uma boa mistura de rotação e rendimento verdadeiro.

SpinWait é um tipo de valor, o que significa que o código de baixo nível pode utilizar SpinWait sem medo de sobrecargas de alocação desnecessárias. O SpinWait geralmente não é útil para aplicativos comuns. Na maioria dos casos, você deve usar as classes de sincronização fornecidas pelo .NET Framework, como Monitor. Para a maioria das finalidades em que a espera de rotação é necessária, no entanto, o SpinWait tipo deve ser preferencial em relação ao Thread.SpinWait método.

Propriedades

Count

Obtém o número de vezes que SpinOnce() foi chamado nessa instância.

NextSpinWillYield

Especifica se a próxima chamada para SpinOnce() produzirá o processador, disparando uma alternância de contexto forçado.

Métodos

Reset()

Redefine o contador de rotação.

SpinOnce()

Executa uma única rotação.

SpinOnce(Int32)

Executa uma única rotação e chama Sleep(Int32) após uma contagem mínima de rotação.

SpinUntil(Func<Boolean>)

Gira até que a condição especificada seja atendida.

SpinUntil(Func<Boolean>, Int32)

Gira até que a condição especificada seja atendida ou até que o tempo limite especificado expire.

SpinUntil(Func<Boolean>, TimeSpan)

Gira até que a condição especificada seja atendida ou até que o tempo limite especificado expire.

Aplica-se a

Acesso thread-safe

Embora SpinWait tenha sido projetado para ser usado em aplicativos simultâneos, ele não foi projetado para ser usado de vários threads simultaneamente. SpinWait os membros não são thread-safe. Se vários threads precisarem girar, cada um deve usar sua própria instância de SpinWait.

Confira também