Поделиться через


Lock Класс

Определение

Примечание

Чтобы использовать этот API предварительной версии, вы должны включить предварительные версии функции в проекте, задав свойству EnablePreviewFeatures значение True в файле проекта. Дополнительные сведения см. на веб-сайте https://aka.ms/dotnet-preview-features.

Предоставляет механизм для достижения взаимного исключения в регионах кода между разными потоками.

public ref class Lock sealed
[System.Runtime.Versioning.RequiresPreviewFeatures]
public sealed class Lock
[<System.Runtime.Versioning.RequiresPreviewFeatures>]
type Lock = class
Public NotInheritable Class Lock
Наследование
Lock
Атрибуты

Комментарии

Класс Lock можно использовать для определения областей кода, требующих взаимоисключающего доступа между потоками процесса( обычно называемые критическими разделами), чтобы предотвратить одновременный доступ к ресурсу. Можно Lock ввести и выйти из нее, где область кода между вводом и выходом является критическим разделом, связанным с блокировкой. Сообщается, что поток, который входит в блокировку, удерживает блокировку или владеет ею до тех пор, пока он не выйдет из блокировки. Не более одного потока может удерживать блокировку в любой момент времени. Поток может содержать несколько блокировок. Поток может войти в блокировку несколько раз перед выходом из нее, например рекурсивно. Поток, который не может сразу ввести блокировку, может ждать, пока не будет введена блокировка или не истечет указанное время ожидания.

При использовании Enter методов или TryEnter для ввода блокировки:

  • Убедитесь, что поток завершает блокировку Exit даже в случае исключений, например в C#, с помощью try/finally блока .
  • Когда блокировка вводится и завершается с помощью метода C# async , убедитесь, что между вводом и выходом нет await . Блокировки удерживаются потоками, и код, следующий за await , может выполняться в другом потоке.

Рекомендуется использовать EnterScope метод с языковой конструкцией, которая автоматически удаляет возвращаемый Lock.Scope объект, например ключевое слово C# using , или использовать ключевое слово C# lock , так как это гарантирует, что блокировка будет завершена в исключительных случаях. Эти шаблоны также могут иметь преимущества в производительности по сравнению с использованием Enter/TryEnter и Exit. В следующем фрагменте кода показаны различные шаблоны для ввода блокировки и выхода из нее.

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(); }
        }
    }
}

При использовании ключевое слово C# lock или аналогичного типа ввода и выхода из блокировки тип выражения должен быть точно таким.System.Threading.Lock Если тип выражения является любым другим, например Object , или универсальным типом, например T, вместо него можно использовать другую реализацию, которая не является взаимозаменяемой (например Monitor, ). Дополнительные сведения см. в соответствующем спецификации компилятора.

Interrupt может прерывать потоки, ожидающие ввода блокировки. В потоках windows STA ожидание блокировок позволяет перекачивать сообщения, которые могут выполнять другой код в том же потоке во время ожидания. Некоторые функции ожиданий могут быть переопределены пользовательским SynchronizationContext.

Примечание

Поток, который входит в блокировку, в том числе несколько раз, например рекурсивно, должен выйти из блокировки одинаковое количество раз, чтобы полностью выйти из блокировки и разрешить другим потокам войти в блокировку. Если поток завершает работу при удержании Lock, поведение Lock объекта становится неопределенным.

Внимание!

Если в пути кода поток может ввести несколько блокировок перед выходом из них, убедитесь, что все пути кода, которые могут входить в любые две из этих блокировок в одном потоке, вводят их в одном порядке. В противном случае это может привести к взаимоблокировкам. Например, учтите, что в одном потоке T1 пути кода вводится блокировка L1 , затем блокировка L2 перед выходом из обоих, а в другом поток T2 пути кода входит в обе блокировки в обратном порядке. В этом сценарии может произойти следующий порядок событий: T1 входит L1, вводит L2, T2T1 пытается ввести L2 и ожидает, пытается войти и ожидает, T2 пытается войти L1 и ожидает. Существует взаимоблокировка между T1 и T2 , которую невозможно устранить, и любые другие потоки, которые пытаются войти в любую из блокировок в будущем, также зависают.

Конструкторы

Lock()

Инициализирует новый экземпляр класса Lock.

Свойства

IsHeldByCurrentThread

Возвращает значение, указывающее, удерживается ли блокировка текущим потоком.

Методы

Enter()

Вводит блокировку, ожидая при необходимости, пока блокировка не будет введена.

EnterScope()

Вводит блокировку, ожидая при необходимости, пока блокировка не будет введена.

Equals(Object)

Определяет, равен ли указанный объект текущему объекту.

(Унаследовано от Object)
Exit()

Завершает блокировку.

GetHashCode()

Служит хэш-функцией по умолчанию.

(Унаследовано от Object)
GetType()

Возвращает объект Type для текущего экземпляра.

(Унаследовано от Object)
MemberwiseClone()

Создает неполную копию текущего объекта Object.

(Унаследовано от Object)
ToString()

Возвращает строку, представляющую текущий объект.

(Унаследовано от Object)
TryEnter()

Пытается войти в блокировку без ожидания.

TryEnter(Int32)

Пытается ввести блокировку, ожидая при необходимости указанного количества миллисекундах, пока блокировка не будет введена.

TryEnter(TimeSpan)

Пытается войти в блокировку, ожидая при необходимости, пока не будет введена блокировка или не истечет указанное время ожидания.

Применяется к