在 C# 中线程化应用程序时锁定 类 和属性的正确方法
Proper method for Locking Classes and Properties when threading applications in C#
我要求编码约定以及在 class.
中对属性和方法使用锁定机制的正确方法
例如我有两个属性和两个方法:
public class FOO
{
private Guid uniqueIdentifier;
object _syncuniqueIdentifier = new object();
public Guid UniqueIdentifier
{
get
{
lock(_syncuniqueIdentifier)
{
return uniqueIdentifier;
}
}
set
{
lock(_syncuniqueIdentifier)
{
uniqueIdentifier = value;
}
}
}
private string userName;
object _syncuserName = new object();
public string UserName
{
get
{
lock(_syncuserName)
{
return userName;
}
}
set
{
lock(_syncuserName)
{
userName = value;
}
}
}
object _syncMyMethod = new object();
public void myMethod(object argument1, object argument2)
{
lock(_syncMyMethod)
{
do work with argument1 and argument2
}
}
}
我是否使用了正确的模式来实现线程,或者我应该改为放置一个对象 _syncLock 并锁定该对象的所有属性和方法?
这样做的编码标准是什么?
是的,假设字段是独立的并且经常更改,您使用的是有效模式。只要在锁下不会发生太多计算,使用单个锁对象也是合理的选择。
如果两个(或更多)字段依赖 属性 级别的锁定将不起作用(即使使用单个对象进行锁定)并且您应该在属性之外锁定或重组 API 以防止只修改一个 属性.
负责锁定的来电者:
// no locks here, all callers to lock
public class FOO {
public Guid UniqueIdentifier {get;set;}
public string UserName {get;set;}
}
// in caller code
usersLock = new object();
List<FOO> users = ...
lock(usersLock)
{
// modify/read users here.
...
}
备选方案API:
public class FOO {
private object idLock = new Object();
// immutable Id class
public class Id {
public Id(....){...}
public Guid UniqueIdentifier {get; private set;}
public string UserName {get; private set;}
}
private Id id;
public Id { get {lock(idLock){ return id;}}
set {lock(idLock){ id = value;}}
}
请注意,根据示例中的字段名称(UniqueIdentifier
和 UserName
),这些字段组合在一起并且在字段级别上锁定将仅提供 "no exceptions" 意义上的线程安全,但是让两个彼此不同步是微不足道的 - 因此可能需要使用上面概述的方法之一。
我要求编码约定以及在 class.
中对属性和方法使用锁定机制的正确方法例如我有两个属性和两个方法:
public class FOO
{
private Guid uniqueIdentifier;
object _syncuniqueIdentifier = new object();
public Guid UniqueIdentifier
{
get
{
lock(_syncuniqueIdentifier)
{
return uniqueIdentifier;
}
}
set
{
lock(_syncuniqueIdentifier)
{
uniqueIdentifier = value;
}
}
}
private string userName;
object _syncuserName = new object();
public string UserName
{
get
{
lock(_syncuserName)
{
return userName;
}
}
set
{
lock(_syncuserName)
{
userName = value;
}
}
}
object _syncMyMethod = new object();
public void myMethod(object argument1, object argument2)
{
lock(_syncMyMethod)
{
do work with argument1 and argument2
}
}
}
我是否使用了正确的模式来实现线程,或者我应该改为放置一个对象 _syncLock 并锁定该对象的所有属性和方法? 这样做的编码标准是什么?
是的,假设字段是独立的并且经常更改,您使用的是有效模式。只要在锁下不会发生太多计算,使用单个锁对象也是合理的选择。
如果两个(或更多)字段依赖 属性 级别的锁定将不起作用(即使使用单个对象进行锁定)并且您应该在属性之外锁定或重组 API 以防止只修改一个 属性.
负责锁定的来电者:
// no locks here, all callers to lock
public class FOO {
public Guid UniqueIdentifier {get;set;}
public string UserName {get;set;}
}
// in caller code
usersLock = new object();
List<FOO> users = ...
lock(usersLock)
{
// modify/read users here.
...
}
备选方案API:
public class FOO {
private object idLock = new Object();
// immutable Id class
public class Id {
public Id(....){...}
public Guid UniqueIdentifier {get; private set;}
public string UserName {get; private set;}
}
private Id id;
public Id { get {lock(idLock){ return id;}}
set {lock(idLock){ id = value;}}
}
请注意,根据示例中的字段名称(UniqueIdentifier
和 UserName
),这些字段组合在一起并且在字段级别上锁定将仅提供 "no exceptions" 意义上的线程安全,但是让两个彼此不同步是微不足道的 - 因此可能需要使用上面概述的方法之一。