Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以有条件地更新可为null的long而不锁定?_C#_Multithreading_Locking_Interlocked - Fatal编程技术网

C# 是否可以有条件地更新可为null的long而不锁定?

C# 是否可以有条件地更新可为null的long而不锁定?,c#,multithreading,locking,interlocked,C#,Multithreading,Locking,Interlocked,我已经很久了?开始时间以保持开始时间 我有多个线程使用非async方法更新startTime,在一个单独的线程中有另一个async方法只读取此值。更新值的方法如下所示: if (startTime == null || (newValue != 0 && newValue < startTime)) { startTime = newValue; } if(startTime==null | |(newValue!=0&&newValue

我已经
很久了?开始时间
以保持开始时间

我有多个线程使用非
async
方法更新
startTime
,在一个单独的线程中有另一个
async
方法只读取此值。更新值的方法如下所示:

if (startTime == null || (newValue != 0 && newValue < startTime))
{
    startTime = newValue;
}
if(startTime==null | |(newValue!=0&&newValue
问题是,编写器线程正在以非常高的频率更新
startTime
,导致大量锁争用。那么,有没有什么方法可以在不锁定的情况下实现这一点(或者有比普通锁更好的锁定机制)

我正在考虑使用
Interlocked
,但由于
if
子句,我认为这是不正确的

编辑:如果需要,我可以将其更改为不可为空。

问题末尾:

编辑:如果需要,我可以将其更改为不可为空

对于不可为空的
long
,您需要一个检查和更新循环(如下所示):

您可以使while子句条件任意复杂,它们实际上是您的
if
检查。您可能还希望/需要在循环内重新计算
newValue

联锁读取
获取初始值。
Interlocated.CompareExchange执行“如果值与上次读取值时的值仍然相同,请提交我的更改”,如果值已更改,则还会获取新的当前值

其他要考虑的事情-你真的需要这个“开始时间”值还是可以在它的位置增加一个简单的整数?这将是互锁的。增量

没有循环和锁定,因此如果您可以适当地修改代码的其他部分,那么如果写入争用仍然很高,则可能值得考虑。

问题结束时:

编辑:如果需要,我可以将其更改为不可为空

对于不可为空的
long
,您需要一个检查和更新循环(如下所示):

您可以使while子句条件任意复杂,它们实际上是您的
if
检查。您可能还希望/需要在循环内重新计算
newValue

联锁读取
获取初始值。
Interlocated.CompareExchange执行“如果值与上次读取值时的值仍然相同,请提交我的更改”,如果值已更改,则还会获取新的当前值


其他要考虑的事情-你真的需要这个“开始时间”值还是可以在它的位置增加一个简单的整数?这将是互锁的。增量

,没有循环和锁定,因此如果写入争用仍然很高,可能值得考虑,如果您可以适当修改代码的其他部分。

您不能使用
联锁
,因为它不支持
可空
。您可以使用int64而不是long。@GabrielPereira,
int64
long
。联锁操作支持的最大大小是64位(至少在.NET中公开)。一个
Nullable
至少是
sizeof(bool)+sizeof(T)
,所以对于
long
你肯定会看。我在你发布的代码中没有看到任何锁定。你不能使用
联锁的
,因为它不支持
Nullable
。你可以用int64代替long。@GabrielPereira,
Int64
long
。联锁操作支持的最大大小为64位(至少在.NET中公开)。一个
Nullable
至少是
sizeof(bool)+sizeof(T)
,所以对于
long
你肯定会看。我没有看到你发布的代码中有任何锁定。谢谢!如果
,为什么我们在
时使用
而不是
?您不必这样做,但它涵盖了“我在评估我的病情时使用的当前
的值不是现在的值”。通常,如果新值也满足了您的条件,您仍然希望将“甚至更好”
newValue
放在它的位置上。所以我们循环直到条件完全不满足。(有可能在不同的条件下,
newValue
会满足条件并产生一个无止境的循环,这就是为什么我总是包括额外的
break
位)。谢谢!如果
,为什么我们在
时使用
而不是
?您不必这样做,但它涵盖了“我在评估我的病情时使用的当前
的值不是现在的值”。通常,如果新值也满足了您的条件,您仍然希望将“甚至更好”
newValue
放在它的位置上。所以我们循环直到条件完全不满足。(在不同的条件下,
newValue
可能会满足该条件并生成一个无止境的循环,这就是为什么我总是包含额外的
break
位的原因)。
var current = Interlocked.Read(ref startTime);
while(current > newValue)
{
  var other = Interlocked.CompareExchange(ref startTime, newValue, current);
  if(other==current) break;
  current = other;
}