Подтвердить что ты не робот

Как заблокировать по параметру метода?

string Get(string key){
   lock(_sync){
    //   DoSomething
   }
}

Если DoSomething зависит только от ключа, я хочу блокировку, зависящую от ключа. Я думаю, что это может быть словарь с объектами синхронизации. Есть ли полное решение?

Что-то вроде настоящего примера Каков наилучший способ блокировки кеша в asp.net?

4b9b3361

Ответ 1

Ну, вы можете создать Dictionary<string, object> и лениво заполнить его объектами для блокировки. Например:

readonly Dictionary<string, object> dictionary = new Dictionary<string, object>();
readonly object dictionaryLock = new object();

string Get(string key) {
    object bodyLock;
    lock (dictionaryLock) {
        if (!dictionary.TryGetValue(key, out bodyLock)) {
            bodyLock = new object();
            dictionary[key] = bodyLock;
        }
    }
    lock (bodyLock) {
        ...
    }
}

Если вам нужно заблокировать то же самое в другом месте, я бы переместил часть "обнаружение блокировки" на вспомогательный метод. Обратите внимание: если вы используете .NET 4, ConcurrentDictionary может сделать это проще и без использования дополнительной блокировки.

Обратите внимание, что нет ничего, что никогда не очистит словарь в этом дизайне... У вас есть фиксированный набор ключей (в этом случае это хорошо) или он может расти навсегда?

Одна вещь, которую вы, кажется, уже поняли: блокировка самого ключа была бы очень плохой идеей. Равные ключи могут быть разными объектами, а если есть и другой код, который блокирует строки, он может помешать этому коду. Блокировка на строках почти всегда неверна:)