【发布时间】:2013-03-18 06:22:14
【问题描述】:
public Response Delete(Request fRequest)
{
Response fResponse = new Response();
try
{
foreach (Record rec in fRequest.Records)
{
string personid = rec.PersonId;
int recordId = rec.RecordId;
EnrollRecord record = (from lst in listEnrolledCandidates
where lst.PersonId == personid && lst.RecordId == recordId
select lst).FirstOrDefault();
lock (lockDelete)
{
listEnrolledCandidates.Remove(record);
int aIndex = record.ArraryIndex;
pvTemplatesArrayList.RemoveAt(aIndex)
}
}
return fResponse;
}
catch (Exception ex)
{
return null;
}
}
在上面的源代码中,锁是在 Remove 语句上保持的。这意味着一次只有一个线程可以执行这三行代码。现在,如果一个线程(例如“A”)正在执行这 3 行,而另一个线程(例如“B”)使用另一个 Request 参数调用“Delete”方法,线程 A 是否有可能在执行时获取 EnrollRecord、personid 和recordid 的更新值Request 对象的操作不同?
【问题讨论】:
-
这可能会有意想不到的行为,为什么锁里面也没有查询enrollrecord的语句。
-
我同意,假设 listEnrolledCandidates 是一个数组列表(从标签推断),那么如果 2 个线程请求删除相同的记录并且都同时获得锁,第一个删除记录和 pvTemplatesArrayList 中的项目,然后下一个不会删除记录(因为如果项目不在 arraylist 中,arraylist.remove 不会做任何事情)但是 pvTemplatesArrayList 将删除数组索引处的项目。我认为会有很多这样的竞争条件。
-
Matt,请提出解决此类问题的方法。
-
请参阅我的建议作为答案。
-
不幸的是,您的问题中缺少 lockDelete 变量的声明。因此无法预测行为将如何。请更新您的代码以包含此信息。
标签: c# multithreading arraylist