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í.
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
public sealed class Lock
type Lock = class
Public NotInheritable Class Lock
- Dědičnost
-
Lock
Poznámky
Lock Třídu lze 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é jako kritické oddíly, aby se zabránilo souběžnému přístupu k prostředku. Je Lock možné zadat a ukončit, kde oblast kódu mezi vstupem a ukončením je kritickou částí přidruženou k zámku. Vlákno, které vstoupí do zámku, se říká, že drží nebo vlastní zámek, dokud zámek nezavře. Maximálně jedno vlákno může v daném okamžiku držet zámek. Vlákno může obsahovat více zámků. Vlákno může před ukončením zadat zámek několikrát, například rekurzivně. Vlákno, které nemůže zadat zámek okamžitě, může počkat, až se zámek zadá nebo dokud nevyprší zadaný časový limit.
Při použití nebo EnterTryEnter metod pro zadání zámku:
- Zajistěte, aby vlákno ukončilo zámek Exit i v případě výjimek, například v jazyce C#, pomocí
try/finallybloku. - Když se zámek zadává a ukončuje v metodě jazyka C#
async, ujistěte se, že mezi vstupem a ukončením neexistuje.awaitZámky se uchovávají ve vláknech a kód, kterýawaitnásleduje po spuštění na jiném vlákně.
Doporučuje se použít metodu EnterScope s konstruktorem jazyka, který automaticky odstraní vrácené Lock.Scope slovo, jako je klíčové slovo jazyka C# using , nebo použít klíčové slovo jazyka C# lock , protože zajistí, aby zámek byl ukončen ve výjimečných případech. Tyto vzory mohou mít také výhody výkonu při používání Enter/TryEnter a Exit. Následující fragment kódu znázorňuje různé vzory pro vstup 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 jazyka C# lock nebo podobného 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, může být použita jiná implementace, která není zaměnitelná (například Monitor). Další informace najdete v příslušné specifikaci kompilátoru.
Interrupt může přerušit vlákna, která čekají na vstup do zámku. Na Windows vlákna STA počkejte na zámky, které umožňují pumpování zpráv, které mohou během čekání spustit jiný kód na stejném vlákně. Některé funkce čekání lze přepsat vlastním SynchronizationContext.
Note
Vlákno, které zadává zámek, včetně vícekrát, například rekurzivně, musí zámek ukončit stejný počet, kolikrát zámek úplně ukončí a umožní ostatním vláknům vstoupit do zámku. Pokud vlákno ukončí při podržení Lock, chování Lock se stane nedefinovaným.
Caution
Pokud v cestě kódu může vlákno před ukončením zadat více zámků, ujistěte se, že všechny cesty kódu, které mohou 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 k zablokování. Představte si například, že na jednom vlákně T1 cesty kódu se před ukončením obou zamkne zámek L1L2 a v jiném vlákně T2 cesty kódu se oba zámky zadávají v inverzním pořadí. V tomto scénáři by mohlo dojít k následujícímu pořadí událostí: enters L1, enters L2, T1T2 pokusí se zadat a čekat, pokusí se zadat L1L2 a čekat. T2T1 Mezi a T2 tím se nedá vyřešit vzájemné zablokování T1 a další vlákna, která se pokusí v budoucnu zadat jeden zámek, se také zablokují.
Konstruktory
| Name | Description |
|---|---|
| Lock() |
Inicializuje novou instanci Lock třídy. |
Vlastnosti
| Name | Description |
|---|---|
| IsHeldByCurrentThread |
Získá hodnotu, která určuje, zda zámek je uložen aktuálním vláknem. |
Metody
| Name | Description |
|---|---|
| Enter() |
Zadá zámek a v případě potřeby čeká, dokud nebude možné zámek zadat. |
| EnterScope() |
Zadá zámek a v případě potřeby čeká, dokud nebude možné zámek zadat. |
| Equals(Object) |
Určuje, zda je zadaný objekt roven aktuálnímu objektu. (Zděděno od Object) |
| Exit() |
Ukončí zámek. |
| GetHashCode() |
Slouží jako výchozí funkce hash. (Zděděno od Object) |
| GetType() |
Získá Type aktuální instance. (Zděděno od Object) |
| MemberwiseClone() |
Vytvoří mělkou kopii aktuálního Object. (Zděděno od Object) |
| ToString() |
Vrátí řetězec, který představuje aktuální objekt. (Zděděno od Object) |
| TryEnter() |
Pokusí se vstoupit do zámku bez čekání. |
| TryEnter(Int32) |
Pokusí se zadat zámek, a v případě potřeby čeká na zadaný počet milisekund, dokud nebude možné zámek zadat. |
| TryEnter(TimeSpan) |
Pokusí se zámek zadat, a v případě potřeby čeká, dokud se zámek nedá zadat nebo dokud nevyprší zadaný časový limit. |