Condividi tramite


SpinWait Struct

Definizione

Fornisce il supporto per l'attesa basata su rotazione.

public value class SpinWait
public struct SpinWait
type SpinWait = struct
Public Structure SpinWait
Ereditarietà
SpinWait

Esempio

Nell'esempio seguente viene illustrato come usare un oggetto 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

Commenti

SpinWait incapsula la logica di rotazione comune. Nei computer a processore singolo, i rendimenti vengono sempre usati invece di attese occupate e nei computer con processori Intel che usano la tecnologia Hyper-Threading, consente di evitare la fame di thread hardware. SpinWait incapsula una buona miscela di filatura e vero rendimento.

SpinWait è un tipo di valore, il che significa che il codice di basso livello può usare SpinWait senza timore di sovraccarichi di allocazione non necessari. SpinWait non è in genere utile per le applicazioni normali. Nella maggior parte dei casi, è consigliabile usare le classi di sincronizzazione fornite da .NET Framework, ad esempio Monitor. Per la maggior parte dei casi in cui è richiesta la rotazione in attesa, tuttavia, il SpinWait tipo deve essere preferito rispetto al Thread.SpinWait metodo .

Proprietà

Count

Ottiene il numero di chiamate di SpinOnce() su questa istanza.

NextSpinWillYield

Ottiene un valore che indica se la chiamata successiva a SpinOnce() comporterà la cessione del processore, attivando un cambio imposto di contesto.

Metodi

Reset()

Reimposta il contatore delle rotazioni.

SpinOnce()

Esegue una sola rotazione.

SpinOnce(Int32)

Esegue un solo spin e chiama Sleep(Int32) dopo un numero spin minimo.

SpinUntil(Func<Boolean>)

Esegue rotazioni finché non è stata soddisfatta la condizione specificata.

SpinUntil(Func<Boolean>, Int32)

Esegue rotazioni finché non è stata soddisfatta la condizione specificata o fino allo scadere del timeout specificato.

SpinUntil(Func<Boolean>, TimeSpan)

Esegue rotazioni finché non è stata soddisfatta la condizione specificata o fino allo scadere del timeout specificato.

Si applica a

Thread safety

Sebbene SpinWait sia progettato per essere usato nelle applicazioni simultanee, non è progettato per essere usato da più thread contemporaneamente. SpinWait i membri non sono thread-safe. Se è necessario ruotare più thread, ognuno deve usare la propria istanza di SpinWait.

Vedi anche