在并行处理方面,我有一个Parallel.For
循环,它对可枚举进行查找,如果找不到要添加的内容,则将其添加。我一直遇到一个问题,其中一个线程修改了可枚举,而另一个线程进行查找,这使它抛出异常。显而易见的解决方案是在查询和条目上都使用lock
,但这有点蛮力。我希望它能够运行多个并发查找,所以我不想在一个线程进行查找时完全锁定它,但是我想禁止它在查找过程中进行添加。有什么办法可以像这样进行两级锁定吗?
答案 0 :(得分:4)
您可能想使用ReaderWriterLock。
private ReaderWriterLockSlim lock = new ReaderWriterLockSlim();
public string Read () {
lock.EnterReadLock ();
try {
return "xxx";
} finally {
lock.ExitReadLock();
}
}
public void Write () {
lock.EnterWriteLock ();
try {
// ...
} finally {
lock.ExiteWriteLock ();
}
}
多个线程可能拥有ReaderWriterLock的“读者”部分,但只有一个人可以拥有“作家”部分(并且有作家的情况下就没有读者)。
答案 1 :(得分:0)
我会考虑使用某种形式的不可变集合和Interlocked
来替换共享实例。
例如您提到“查找”,那么ImmutableDictionary
会是一个很好的匹配吗?
然后进行查找和更新,您将得到以下内容:
var local = sharedReference;
while(!local.ContainsKey(lookupValue))
{
var newValue = /* Whatever */
var newLocal = local.Add(lookupValue,newValue);
var result = Interlocked.CompareExchange(ref sharedReference, newLocal, local);
if(result == local) break;
local = result;
}
//At this point, local definitely contains a key for lookupValue