【发布时间】:2019-08-14 08:25:17
【问题描述】:
在我的 BL 中,我希望在另一个线程已经在进行中时不执行某个代码。
问题是代码可以(按需求)为每个客户执行一次,但不能为同一客户执行两次
我已经使用 C# ConcurrentDictionary 来跟踪已经在进行中的客户,当执行完成时,我已将它们从 ConcurrentDictionary 中删除,如果我尝试从 @ 中删除客户 ID 会发生什么情况987654324@ 而另一个线程正在尝试添加(相同或不同的键)? ConcurrentDictionary 写锁和try remove 会失败吗?
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");
}
}
}
this.Log().Fatal("this should never happens"); 会发生吗?
如果对同一个键同时执行 try add 和 try remove 会发生什么?
如果它针对不同的键执行会发生什么?
【问题讨论】:
-
Code(如果有帮助的话)。
-
您已经实现了一个可以正常工作的并发锁定机制。
TryAdd和TryRemove都是对集合的原子操作。 -
我的问题是,如果 tryremove 由于 ConcurrentDictionary 锁定的竞争条件而失败,这将导致用户在此功能上死锁(因为他将永远在 ConcurrentDictionary 中),它会发生吗?删除是否会由于比赛条件而失败
-
只有一个线程会成功添加
customerId并继续,最后删除。除非有其他方法可以并行运行并以某种方式删除customerId,否则“这永远不会发生”永远不会发生。
标签: c# multithreading dictionary concurrency