Lock 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
注意
若要使用此预览 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
可以进入和退出,其中进入和退出之间的代码区域是与锁关联的关键部分。 进入锁的线程据说会保留或拥有锁,直到它退出锁。 最多一个线程可以在任何给定时间持有锁。 一个线程可以保留多个锁。 线程在退出锁之前可以多次进入锁,例如以递归方式。 无法立即进入锁的线程可以等到可以输入锁或指定的超时过期。
- 确保线程退出
try/finally
锁Exit,即使出现异常(例如在 C# 中使用块)。 - 在 C#
async
方法中进入和退出锁时,请确保进入和退出之间没有await
。 锁由线程持有,后面的代码await
可能在不同的线程上运行。
建议将 EnterScope 方法与自动释放返回Lock.Scope的语言构造(例如 C# using
关键字 (keyword) )结合使用,或使用 C# lock
关键字 (keyword) ,因为这些方法可确保在特殊情况下退出锁。 与使用 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
关键字 (keyword) 或类似项进入和退出锁时,表达式的类型必须精确System.Threading.Lock
为 。 如果表达式的类型是任何其他类型,例如 Object
或泛型类型(如 T
),则可以改用其他不可互换的实现 (如 Monitor) 。 有关详细信息,请参阅相关的 编译器规范。
Interrupt 可以中断等待进入锁的线程。 在 Windows STA 线程上,等待锁允许在等待期间在同一线程上运行其他代码的消息泵送。 自定义 SynchronizationContext可以重写等待的某些功能。
注意
进入锁的线程(包括多次(例如递归)必须退出锁的次数相同才能完全退出锁并允许其他线程进入锁。 如果线程在保留 Lock
时退出,则 的行为 Lock
将变为未定义。
注意
如果在代码路径上,某个线程在退出之前可能进入多个锁,请确保可能在同一线程上输入其中任意两个锁的所有代码路径都按相同的顺序输入这些锁。 否则,可能导致死锁。 例如,假设在一个代码路径线程 T1
进入锁 L1
,然后锁定 L2
后退出这两个线程,在另一个代码路径线程 T2
上以相反的顺序进入这两个锁。 在这种情况下,可能会发生以下事件顺序:enters 、enters L2
、T1
尝试输入L2
和等待、T2
尝试输入L1
和等待。 T2
L1
T1
和 T2
之间存在T1
无法解决的死锁,将来尝试进入任一锁的任何其他线程也会挂起。
构造函数
Lock() |
初始化 Lock 类的新实例。 |
属性
IsHeldByCurrentThread |
获取一个值,该值指示锁是否由当前线程持有。 |
方法
Enter() |
进入锁,并在必要时等待,直到可以输入锁。 |
EnterScope() |
进入锁,并在必要时等待,直到可以输入锁。 |
Equals(Object) |
确定指定对象是否等于当前对象。 (继承自 Object) |
Exit() |
退出锁。 |
GetHashCode() |
作为默认哈希函数。 (继承自 Object) |
GetType() |
获取当前实例的 Type。 (继承自 Object) |
MemberwiseClone() |
创建当前 Object 的浅表副本。 (继承自 Object) |
ToString() |
返回表示当前对象的字符串。 (继承自 Object) |
TryEnter() |
尝试在不等待的情况下进入锁。 |
TryEnter(Int32) |
尝试进入锁,根据需要等待指定的毫秒数,直到可以输入锁。 |
TryEnter(TimeSpan) |
尝试进入锁,如有必要,请等待,直到可以输入锁或指定的超时过期。 |