Скажем, у меня есть эта функция (предположим, что я получаю доступ к кэшу потокобезопасным способом):
object GetCachedValue(string id)
{
if (!Cache.ContainsKey(id))
{
//long running operation to fetch the value for id
object value = GetTheValueForId(id);
Cache.Add(id, value);
}
return Cache[id];
}
Я хочу, чтобы два потока не выполняли "длительную операцию" одновременно для одного и того же значения. Очевидно, я могу обернуть все это в lock(), но тогда вся функция блокирует независимо от значения, и я хочу, чтобы два потока могли выполнять длительную операцию, пока они ищут разные идентификаторы.
Есть ли встроенный механизм блокировки для блокировки на основе значения, чтобы один поток мог блокировать, в то время как другой поток завершает длительную операцию, поэтому мне не нужно делать это дважды (или N раз)? В идеале, если длительная работа выполняется в одном потоке, ни один другой поток не сможет сделать это для одного и того же значения id.
Я мог бы свернуть свой собственный, поместив идентификатор в HashSet, а затем удалив их после завершения операции, но это похоже на взлом.