SpinWait Struktura
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Poskytuje podporu pro čekání založené na spinu.
public value class SpinWait
public struct SpinWait
type SpinWait = struct
Public Structure SpinWait
- Dědičnost
Příklady
Následující příklad ukazuje, jak použít 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
Poznámky
SpinWait zapouzdřuje běžnou logiku otáčení. Na počítačích s jedním procesorem se výnosy vždy používají místo zaneprázdněných čekání a na počítačích s procesory Intel, které využívají technologii Hyper-Threading, pomáhá zabránit hardwarovému hladovění vláken. SpinWait zapouzdřuje dobrou směs otáčení a skutečného výnosu.
SpinWait je typ hodnoty, což znamená, že kód nízké úrovně může využívat SpinWait bez obav z zbytečných režijních nákladů na přidělení. SpinWait není obecně užitečný pro běžné aplikace. Ve většině případů byste měli použít synchronizační třídy poskytované rozhraním .NET Framework, například Monitor. Pro většinu účelů, kdy je vyžadováno čekání na číselník, SpinWait by se však měl upřednostňovat typ před metodou Thread.SpinWait .
Vlastnosti
Count |
Získá počet, kolikrát SpinOnce() byl volána v této instanci. |
NextSpinWillYield |
Získá, zda další volání, aby SpinOnce() procesor, který aktivuje vynucený kontextový přepínač. |
Metody
Reset() |
Obnoví číselník. |
SpinOnce() |
Provede jeden číselník. |
SpinOnce(Int32) |
Provede jeden číselník a volání Sleep(Int32) po minimálním počtu čísel. |
SpinUntil(Func<Boolean>) |
Zatočí do doby, než bude zadaná podmínka splněna. |
SpinUntil(Func<Boolean>, Int32) |
Zatočí do doby, než bude zadaná podmínka splněna nebo dokud nevypršel zadaný časový limit. |
SpinUntil(Func<Boolean>, TimeSpan) |
Zatočí do doby, než bude zadaná podmínka splněna nebo dokud nevypršel zadaný časový limit. |
Platí pro
Bezpečný přístup z více vláken
I když SpinWait je navržený tak, aby se používal v souběžných aplikacích, není navržen tak, aby se používal z více vláken současně. SpinWait členy nejsou bezpečné pro přístup z více vláken. Pokud více vláken musí spinovat, každý by měl používat svou vlastní instanci SpinWait.