我正在尝试在 C# 中创建线程安全属性,并且我想确保我处于正确的路径上 - 这是我所做的 -
private readonly object AvgBuyPriceLocker = new object();
private double _AvgBuyPrice;
private double AvgBuyPrice
{
get
{
lock (AvgBuyPriceLocker)
{
return _AvgBuyPrice;
}
}
set
{
lock (AvgBuyPriceLocker)
{
_AvgBuyPrice = value;
}
}
}
阅读这篇文章,这似乎不是正确的做法 -
C# 线程安全与 get/set https://stackoverflow.com/questions/505515/c-thread-safety-with-get-set
然而,这篇文章似乎另有暗示,
http://www.codeproject.com/KB/cs/Synchronized.aspx http://www.codeproject.com/KB/cs/Synchronized.aspx
有人有更明确的答案吗?
Edit:
我想为此属性执行 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);
}
}
}
}
我对使我的代码线程安全还很陌生,所以请随时告诉我我是否以完全错误的方式进行操作!
Will
正如您所写的那样,锁是毫无意义的。例如,读取变量的线程将:
- 获取锁。
- 读取值。
- 释放锁。
- 以某种方式使用读取值。
在步骤 3 之后,没有什么可以阻止另一个线程修改该值。由于 .NET 中的变量访问是原子的(请参见下面的警告),因此锁实际上并没有实现太多目的:只是增加了开销。与解锁示例对比:
- 读取值。
- 以某种方式使用读取值。
另一个线程可能会更改步骤 1 和步骤 2 之间的值,这与锁定示例没有什么不同。
如果要确保在进行某些处理时状态不会改变,则必须读取该值并使用该值进行处理在锁的上下文中:
- 获取锁。
- 读取值。
- 以某种方式使用读取值。
- 释放锁。
话虽如此,在某些情况下,您在访问变量时需要锁定。这些通常是由于底层处理器的原因造成的:double
例如,变量不能作为 32 位机器上的单个指令进行读取或写入,因此您必须锁定(或使用替代策略)以确保不会读取损坏的值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)