我正在尝试在 C# 中创建线程安全属性,我想确保我在正确的路径上 - 这是我所做的 -
private readonly object AvgBuyPriceLocker = new object();
private double _AvgBuyPrice;
private double AvgBuyPrice
{
get
{
lock (AvgBuyPriceLocker)
{
return _AvgBuyPrice;
}
}
set
{
lock (AvgBuyPriceLocker)
{
_AvgBuyPrice = value;
}
}
}
阅读这篇文章,似乎这不是正确的做法 -
然而,这篇文章似乎另有建议,
http://www.codeproject.com/KB/cs/Synchronized.aspx
有没有人有更明确的答案?
编辑:
我想为此属性执行 Getter/Setter 的原因是 b/c 我实际上希望它在设置时触发一个事件 - 所以代码实际上是这样的 -
public class PLTracker
{
public PLEvents Events;
private readonly object AvgBuyPriceLocker = new object();
private double _AvgBuyPrice;
private double AvgBuyPrice
{
get
{
lock (AvgBuyPriceLocker)
{
return _AvgBuyPrice;
}
}
set
{
lock (AvgBuyPriceLocker)
{
Events.AvgBuyPriceUpdate(value);
_AvgBuyPrice = value;
}
}
}
}
public class PLEvents
{
public delegate void PLUpdateHandler(double Update);
public event PLUpdateHandler AvgBuyPriceUpdateListener;
public void AvgBuyPriceUpdate(double AvgBuyPrice)
{
lock (this)
{
try
{
if (AvgBuyPriceUpdateListener!= null)
{
AvgBuyPriceUpdateListener(AvgBuyPrice);
}
else
{
throw new Exception("AvgBuyPriceUpdateListener is null");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
我对确保我的代码线程安全还很陌生,所以如果我以完全错误的方式进行处理,请随时告诉我!
将
最佳答案
如您所写,锁是毫无意义的。例如,读取变量的线程将:
- 获取锁。
- 读取值。
- 释放锁。
- 以某种方式使用读取的值。
在第 3 步之后,没有什么可以阻止另一个线程修改该值。由于 .NET 中的变量访问是原子的(请参阅下面的警告),锁在这里实际上并没有实现太多:只是增加了开销。与解锁示例对比:
- 读取值。
- 以某种方式使用读取的值。
另一个线程可能会更改第 1 步和第 2 步之间的值,这与锁定的示例没有什么不同。
如果要确保在进行某些处理时状态不会更改,则必须在锁的上下文中读取值并使用该值进行处理:
- 获取锁。
- 读取值。
- 以某种方式使用读取的值。
- 释放锁。
话虽如此,有些情况下您需要在访问变量时进行锁定。这些通常是由于底层处理器的原因:例如,double
变量不能在 32 位机器上作为单个指令读取或写入,因此您必须锁定(或使用替代策略)以确保不读取损坏的值。
关于c# - C# 中的线程安全属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7161413/