private const string ContainerKey = "ModelsKey";
private static object _sync=new object();
private ConcurrentDictionary<string, Model> Container
{
get
{
var tmp = HttpContext.Current.Application[ContainerKey] as ConcurrentDictionary<string, Model>;
if (tmp == null)
{
lock (_sync)
{
tmp=HttpContext.Current.Application[ContainerKey] as ConcurrentDictionary<string, Model>;
if (tmp!=null)
{
return tmp;
}
tmp = new ConcurrentDictionary<string, Model>();
HttpContext.Current.Application[ContainerKey] = tmp;
}
}
return tmp;
}
}
1. Решарпер говорит, что внутри lock'а строка tmp=HttpContext.Current.Application[ContainerKey] — не нужна и tmp все равно равен null. Я ему не верю. Кто прав?
2. Является ли пример потокобезопасным?
Здравствуйте, Аноним, Вы писали:
А>1. Решарпер говорит, что внутри lock'а строка tmp=HttpContext.Current.Application[ContainerKey] — не нужна и tmp все равно равен null. Я ему не верю. Кто прав?
Решарпер не прав.
А>2. Является ли пример потокобезопасным?
да
Здравствуйте, Аноним, Вы писали:
А>2. Является ли пример потокобезопасным?
Формально — нет. Бо свойство Application не является потокобезопасным.
Re[2]: Снова про double-check locking
От:
Аноним
Дата:
11.11.13 07:56
Оценка:
Здравствуйте, mucks, Вы писали:
M>Здравствуйте, Аноним, Вы писали:
А>>2. Является ли пример потокобезопасным?
M>Не является. HttpContext.Current.Application глобальная переменная, а объект синхронизации в пределах класса.
Я правильно Вас понимаю, Вы предлагаете использовать что-то вроде lock(HttpContext.Current.Application) ?
Хочется понять есть ли в этом смысл.
У меня ситуация следующая: в Application (а так же в Session) хранится куча строго-типизированных коллекций. По аналогии с приведенным примером, но ContainerKey отличается.
Гарантируется, что доступ к данным коллекциям происходит только через свойство Container (private), и никто напрямую с Application/Session работать не будет. Не вижу необходимости синхронизировать любое добавление в Application/Session, что плохого случится если одновременно будет добавляться элементы с ключами "ModelsKey" и "OtherModelsKey" ?
А>1. Решарпер говорит, что внутри lock'а строка tmp=HttpContext.Current.Application[ContainerKey] — не нужна и tmp все равно равен null. Я ему не верю. Кто прав?
Он неправ
А>2. Является ли пример потокобезопасным?
It depends. Если никто другим способом не лезет доставать твой контейнер, то да.
А вообще double-check lock может отказаться непотокобезопасным, это надо помнить.
Здравствуйте, gandjustas, Вы писали:
А>>2. Является ли пример потокобезопасным? G>It depends. Если никто другим способом не лезет доставать твой контейнер, то да. G>А вообще double-check lock может отказаться непотокобезопасным, это надо помнить.
Можно пример, когда это будет непотокобезопасным? Если вы имеете ввиду вариант, когда вместо локальный переменной использования не-volatile поля класса, то про это я знаю, но у меня вроде как lock должен гарантировать отсутствие сайд-эффектов от переупорядочиваний/кеширований и прочей_магии.
G>Кстати лучше пользоватся http://msdn.microsoft.com/en-us/library/system.web.httpapplicationstate.lock(v=vs.110).aspx, а не ручной блокировкой.
Про это я написал в ответ на сообщение mucks. У меня гарантируется доступ к элементу коллекции Application через свойство Container, и я не вижу смысл синхронизировать любые попытки добавления в коллекцию.
Хотя особых минусов блокировать все коллекцию я не вижу — наверное кину монетку =)
Здравствуйте, Аноним, Вы писали:
А>Я правильно Вас понимаю, Вы предлагаете использовать что-то вроде lock(HttpContext.Current.Application) ?
Нет, я этого не предлагаю В общем случае, возможность несинхронизированного доступа остается такая же.
А>Хочется понять есть ли в этом смысл. А>У меня ситуация следующая: в Application (а так же в Session) хранится куча строго-типизированных коллекций. По аналогии с приведенным примером, но ContainerKey отличается. А>Гарантируется, что доступ к данным коллекциям происходит только через свойство Container (private), и никто напрямую с Application/Session работать не будет. Не вижу необходимости синхронизировать любое добавление в Application/Session, что плохого случится если одновременно будет добавляться элементы с ключами "ModelsKey" и "OtherModelsKey" ?
Если это только ваш код и вы уверены, что описанные допущения нарушены не будут, то проблем с многопоточностью не будет. И даже Container можно паблик сделать. Но строго говоря код не является потокобезопасным, поскольку защищаемые данные видны всем.