C# 如果try add和remove上存在共谋,那么ConcurrentDictionary中会发生什么情况?
在我的BL中,我希望当另一个线程已经在运行时,某个代码不会被执行 问题在于,代码可以(按需)为每个客户执行一次,但不能为同一客户执行两次 我已经使用C#C# 如果try add和remove上存在共谋,那么ConcurrentDictionary中会发生什么情况?,c#,multithreading,dictionary,concurrency,C#,Multithreading,Dictionary,Concurrency,在我的BL中,我希望当另一个线程已经在运行时,某个代码不会被执行 问题在于,代码可以(按需)为每个客户执行一次,但不能为同一客户执行两次 我已经使用C#ConcurrentDictionary来跟踪已经在进行的客户,当执行完成时,我已经将它们从ConcurrentDictionary中删除,如果我试图在另一个线程尝试添加时从ConcurrentDictionary中删除客户id,会发生什么情况(相同或不同的密钥)ConcurrentDictionary是否锁定写入,并且尝试删除将失败 priva
ConcurrentDictionary
来跟踪已经在进行的客户,当执行完成时,我已经将它们从ConcurrentDictionary
中删除,如果我试图在另一个线程尝试添加时从ConcurrentDictionary
中删除客户id,会发生什么情况(相同或不同的密钥)ConcurrentDictionary是否锁定写入,并且尝试删除将失败
private static readonly ConcurrentDictionary<int, DateTime> m_customerInProgress = new ConcurrentDictionary<int, DateTime>();
public void ExecuteLogic(int customerId)
{
if (m_customerInProgress.TryAdd(customerId, DateTime.Now) == false)
{
this.Log().Info("customer in progress ");
return;
}
try
{
DoSomething();
}
catch (Exception ex)
{
this.Log().Info("DoSomething failed ");
}
finally
{
DateTime startDateTime;
if (m_customerInProgress.TryRemove(customerId, out startDateTime) == false)
{
this.Log().Fatal("this should never happens");
}
else
{
this.Log().Info("customer finished execution");
}
}
}
私有静态只读ConcurrentDictionary m_CustomerProgress=new ConcurrentDictionary();
public void ExecuteLogic(int customerId)
{
if(m_customerInProgress.TryAdd(customerId,DateTime.Now)=false)
{
this.Log().Info(“正在处理的客户”);
返回;
}
尝试
{
DoSomething();
}
捕获(例外情况除外)
{
this.Log().Info(“DoSomething失败”);
}
最后
{
日期时间开始日期时间;
if(m_customerInProgress.TryRemove(customerId,out startDateTime)==false)
{
this.Log().Fatal(“这永远不会发生”);
}
其他的
{
this.Log().Info(“客户已完成执行”);
}
}
}
this.Log().Fatal(“这永远不会发生”);
会发生吗
如果try add和try remove对同一个键同时执行,会发生什么情况
如果对不同的键执行,会发生什么情况?您的代码很好。
TryAdd
只有在TryRemove
完成后才会成功
唯一奇怪的是,在
TryRemove
返回线程(我们称之为T1
)后,另一个线程被挂起(我们称之为T2
)调用您的方法。它可能会在T1
恢复执行之前执行整个方法,因此您的日志记录可能会相互交织。您的代码很好。TryAdd
只有在TryRemove
完成后才会成功
唯一奇怪的是,在
TryRemove
返回线程(我们称之为T1
)后,另一个线程(我们称之为T2
)调用您的方法。它可能会在T1
恢复执行之前执行整个方法,因此您的日志记录可能会相互交织。(如果有帮助的话)。您已经实现了一个并发锁定机制,可以正常工作。TryAdd
和TryRemove
都是集合上的原子操作。我的问题是,如果TryRemove由于ConcurrentDictionary锁上的争用条件而失败,这将导致用户在此函数上出现死锁(因为他将永远在ConcurrentDictionary中),这会发生吗?删除是否会因为争用条件而失败?只有一个线程将成功添加customerId
并继续,最后将其删除。除非有其他方法可以并行运行并以某种方式删除该customerId
“这永远不会发生”不应该发生。(如果有帮助的话)。您已经实现了一个并发锁定机制,可以正常工作。TryAdd
和TryRemove
都是集合上的原子操作。我的问题是,如果TryRemove由于ConcurrentDictionary锁上的争用条件而失败,这将导致用户在此函数上出现死锁(因为他将永远在ConcurrentDictionary中),这会发生吗?删除是否会因为争用条件而失败?只有一个线程将成功添加customerId
并继续,最后将其删除。除非有其他方法可以并行运行并以某种方式删除该customerId
“这永远不会发生”我的问题是,如果tryremove由于ConcurrentDictionary锁上的争用条件而失败,这将导致用户在此函数上出现死锁(因为他将永远在ConcurrentDictionary中),它会发生吗?删除是否会因争用而失败cndition@eliavra-TryRemove
失败的唯一方法是,如果项目首先不在字典中。你的代码结构意味着,如果TryAdd
成功,你只会调用TryRemove
。没有竞争条件。我的问题是,如果tryremove将由于ConcurrentDictionary锁上的争用条件而失败,这将导致用户在此函数上出现死锁(因为他将永远在ConcurrentDictionary中),它会发生吗?删除是否会因争用而失败cndition@eliavra-TryRemove
失败的唯一方法是,如果项目首先不在字典中。代码的结构意味着,如果TryAdd
成功,您将只调用TryRemove
。不存在争用条件。