Lock Třída
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í.
Poznámka
Pokud chcete toto rozhraní API verze Preview používat, musíte ve svém projektu povolit funkce Preview, a to nastavením vlastnosti EnablePreviewFeatures
na True
v souboru projektu. Další informace najdete na webu https://aka.ms/dotnet-preview-features.
Poskytuje mechanismus pro dosažení vzájemného vyloučení v oblastech kódu mezi různými vlákny.
public ref class Lock sealed
[System.Runtime.Versioning.RequiresPreviewFeatures]
public sealed class Lock
[<System.Runtime.Versioning.RequiresPreviewFeatures>]
type Lock = class
Public NotInheritable Class Lock
- Dědičnost
-
Lock
- Atributy
Poznámky
Třída Lock se dá použít k definování oblastí kódu, které vyžadují vzájemně se vylučující přístup mezi vlákny procesu, běžně označovanými jako kritické oddíly, aby se zabránilo souběžnému přístupu k prostředku. Lze Lock
zadat a ukončit, kde oblast kódu mezi vstupem a výstupem je kritickou částí přidruženou k zámku. Vlákno, které vstupuje do zámku, se říká, že zámek drží nebo vlastní, dokud zámek opustí. Maximálně jedno vlákno může mít v daném okamžiku zámek. Vlákno může obsahovat více zámků. Vlákno může před ukončením několikrát zadat zámek, například rekurzivně. Vlákno, které nemůže zadat zámek okamžitě, může počkat na zadání zámku nebo na vypršení zadaného časového limitu.
Při použití Enter metody nebo TryEnter k zadání zámku:
- Ujistěte se, že vlákno ukončí zámek Exit i v případě výjimek, jako je například v jazyce C#, pomocí
try/finally
bloku. - Když se zámek zadává a ukončuje v metodě jazyka C#
async
, ujistěte se, že mezi vstupem a ukončením není žádnýawait
zámek. Zámky jsou drženy vlákny a kód následující za objektemawait
může běžet v jiném vlákně.
Doporučujeme použít metodu EnterScope s konstruktorem jazyka, který automaticky odstraní vrácené Lock.Scope klíčové slovo, jako je klíčové slovo C# using
, nebo klíčové slovo jazyka C# lock
, které zajistí, že se zámek ve výjimečných případech ukončí. Tyto vzory můžou mít oproti používání Enter/TryEnter
a Exit
také výhody z hlediska výkonu. Následující fragment kódu znázorňuje různé vzory pro zadání a ukončení zámku.
public sealed class ExampleDataStructure
{
private readonly Lock _lockObj = new();
public void Modify()
{
lock (_lockObj)
{
// Critical section associated with _lockObj
}
using (_lockObj.EnterScope())
{
// Critical section associated with _lockObj
}
_lockObj.Enter();
try
{
// Critical section associated with _lockObj
}
finally { _lockObj.Exit(); }
if (_lockObj.TryEnter())
{
try
{
// Critical section associated with _lockObj
}
finally { _lockObj.Exit(); }
}
}
}
Při použití klíčového slova C# lock
nebo podobného k zadání a ukončení zámku musí být typ výrazu přesně System.Threading.Lock
. Pokud je typ výrazu cokoli jiného, například Object
nebo obecný typ, jako T
je , můžete místo toho použít jinou implementaci, která není zaměnitelná (například Monitor). Další informace najdete v příslušné specletu kompilátoru.
Interrupt může přerušit vlákna, která čekají na zadání zámku. Ve vláknech Windows STA čekání na zámky umožňují pumpování zpráv, které mohou během čekání spustit jiný kód ve stejném vlákně. Některé funkce čekání lze přepsat vlastním SynchronizationContext.
Poznámka
Vlákno, které vstupuje do zámku, včetně vícekrát, například rekurzivně, musí zámek opustit stejný početkrát, aby se zámek úplně ukončil a umožnilo ostatním vláknům vstoupit do zámku. Pokud vlákno opustí při držení Lock
, chování objektu Lock
se nedefinuje.
Upozornění
Pokud v cestě ke kódu může vlákno zadat více zámků před jejich ukončením, ujistěte se, že všechny cesty kódu, které by mohly zadat jakékoli dva z těchto zámků ve stejném vlákně, je zadávají ve stejném pořadí. Jinak by to mohlo vést ke vzájemným zablokováním. Představte si například, že na jednom podprocesu T1
cesty kódu zadá zámek L1
a pak zámek L2
před ukončením obou a na jiném podproces T2
cesty kódu zadá oba zámky v inverzním pořadí. V takovém scénáři by mohlo dojít k následujícímu pořadí událostí: zadá , zadá , pokusí se zadat L2
a počká, T2
pokusí se zadat L1
a čeká. T1
L2
T2
L1
T1
Mezi a T2
dochází ke vzájemnému zablokováníT1
, které se nedá vyřešit, a všechna další vlákna, která se v budoucnu pokusí zadat zámek, se také zablokují.
Konstruktory
Lock() |
Inicializuje novou instanci Lock třídy . |
Vlastnosti
IsHeldByCurrentThread |
Získá hodnotu, která označuje, zda zámek je držen aktuální vlákno. |
Metody
Enter() |
Vloží zámek a v případě potřeby počká, až bude zámek možné zadat. |
EnterScope() |
Vloží zámek a v případě potřeby počká, až bude zámek možné zadat. |
Equals(Object) |
Určí, zda se zadaný objekt rovná aktuálnímu objektu. (Zděděno od Object) |
Exit() |
Ukončí zámek. |
GetHashCode() |
Slouží jako výchozí hashovací funkce. (Zděděno od Object) |
GetType() |
Type Získá z aktuální instance. (Zděděno od Object) |
MemberwiseClone() |
Vytvoří mělkou kopii aktuálního Objectsouboru . (Zděděno od Object) |
ToString() |
Vrátí řetězec, který představuje aktuální objekt. (Zděděno od Object) |
TryEnter() |
Pokusí se zadat zámek bez čekání. |
TryEnter(Int32) |
Pokusí se zadat zámek a v případě potřeby čeká na zadaný počet milisekund, dokud zámek nebude možné zadat. |
TryEnter(TimeSpan) |
Pokusí se zadat zámek a v případě potřeby čeká na zadání zámku nebo na vypršení zadaného časového limitu. |