Здравствуйте, _FRED_, Вы писали:
_FR>В документации к goto приведено несколько сценариев его использования, но, подходя к програмированию разумно, не все их следует использовать, тем более, повсеместно. Так же и здесь: если дана ссылку на какую-то цитату, это вовсе не означает, что всё произведение в целом есть истина.
_FR>В МСДН есть не мало очень умных мыслей. А есть и просто вредные.
_FR>В примере в статье, на которую вы ссылаетесь (как, кажется, и везде в МСДН), lockThis даже без ридлонли объявлен — что конечно же никак не влият на _работоспособность_ кода, но может оказаться весьма важным при использовании/поддержке/рефакторинге/переписывании.
Всё вышесказанное не имеет отношения к обсуждаемой теме.
_FR>Например, в данной статье никак не сказано, как процитированный кусок сочитается с SRP, однако весьма разумно держать это у себя в голове постоянно, и экземпляры объектов (" container object") использовать для одних целей (для которых они напрямую предназначены), а для синхронизации использовать нечто другое, самостоятельное.
SRP тут не нарушается, потому что тот факт, что мы на нём лочимся, никак не меняет его функционал — просто делает _наш код_ потокобезопасным.
Здравствуйте, _FRED_, Вы писали:
_FR>Почему слово public обязательно следует понимать буквально? Ничто не мешает понимать его как видимое где-то снаружи.
А что кроме public является "видимым где-то снаружи"? Снаружи чего кстати?
Здравствуйте, koandrew, Вы писали:
_FR>>В документации к goto приведено несколько сценариев его использования, но, подходя к програмированию разумно, не все их следует использовать, тем более, повсеместно. Так же и здесь: если дана ссылку на какую-то цитату, это вовсе не означает, что всё произведение в целом есть истина. _FR>>В МСДН есть не мало очень умных мыслей. А есть и просто вредные. _FR>>В примере в статье, на которую вы ссылаетесь (как, кажется, и везде в МСДН), lockThis даже без ридлонли объявлен — что конечно же никак не влият на _работоспособность_ кода, но может оказаться весьма важным при использовании/поддержке/рефакторинге/переписывании. K>Всё вышесказанное не имеет отношения к обсуждаемой теме.
Имеет Я же в ответ на свою цитату получил другую без какого-то бы нибыло разъяснения.
_FR>>Например, в данной статье никак не сказано, как процитированный кусок сочитается с SRP, однако весьма разумно держать это у себя в голове постоянно, и экземпляры объектов (" container object") использовать для одних целей (для которых они напрямую предназначены), а для синхронизации использовать нечто другое, самостоятельное. K>SRP тут не нарушается, потому что тот факт, что мы на нём лочимся, никак не меняет его функционал — просто делает _наш код_ потокобезопасным.
Чем потокобезопастность нашего кода, в случае использования специального объекта синхронизации будет отличаться? А то, что SRP нарушается видно очень хорошо: при необходимости реализации другого сценария потокобезопастности может потребоваться синхронизироваться по другому объекту. Если одна синхронизация делается на самом неком объекте, а другая — на объекте сбоку, то возникает вопрос — почему по сути одно и то же реализовано по-разному?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, koandrew, Вы писали:
K>Здравствуйте, Константин Л., Вы писали:
КЛ>>1. многими КЛ>>2. это не "плодить сущности", это писать безопасный код
K>Аргументация?
лочась на объект, для этого не предназначенный, ты повышаешь энтропию. объекты синхронизации это не лишние сущности. я предпочитаю заводить readonly object и спать спокойно.
Здравствуйте, koandrew, Вы писали:
_FR>>Почему слово public обязательно следует понимать буквально? Ничто не мешает понимать его как видимое где-то снаружи.
K>А что кроме public является "видимым где-то снаружи"?
Как минимум, то, что называется internal.
K>Снаружи чего кстати?
Снаружи — означает "извне". Чего именно — да чего угодно, никаких не соответствий не вижу.
Например, снаружи вложенного private-класса видны его public-члены, но более "снаружи" уже нет. Попадают ли такие public-члены под термин "public", используемый в гайдлайнах? Чаще всего, нет. Но в некоторой узкой и очень близкой области эпсилон эта непубличность может быть очень даже заметна. Поэтому под "public" в цитате не следует понимать все открытые члены открытых типов, видимые в сторонних сборках. А именно это и подразумевается в MSDN.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Чем потокобезопастность нашего кода, в случае использования специального объекта синхронизации будет отличаться? А то, что SRP нарушается видно очень хорошо: при необходимости реализации другого сценария потокобезопастности может потребоваться синхронизироваться по другому объекту. Если одна синхронизация делается на самом неком объекте, а другая — на объекте сбоку, то возникает вопрос — почему по сути одно и то же реализовано по-разному?
SRP не про то, что нельзя один и тот же класс использовать для разных целей, он про то, что конкретный экземпляр класса нужно использовать для одной цели. Если определить цель как "потокобезопасная коллекция", то всё встаёт на свои места.
Вообще же в реальности я обычно в таком случае использую потокобезопасные агрегаты коллекций, которые обеспечивают потокобезопасность внутри себя, позволяя освободить внешний код то мусора, вызванного необходимостью синхронизации.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, koandrew, Вы писали:
_FR>>>Почему слово public обязательно следует понимать буквально? Ничто не мешает понимать его как видимое где-то снаружи.
K>>А что кроме public является "видимым где-то снаружи"?
_FR>Как минимум, то, что называется internal.
K>>Снаружи чего кстати?
_FR>Снаружи — означает "извне". Чего именно — да чего угодно, никаких не соответствий не вижу.
_FR>Например, снаружи вложенного private-класса видны его public-члены, но более "снаружи" уже нет. Попадают ли такие public-члены под термин "public", используемый в гайдлайнах? Чаще всего, нет. Но в некоторой узкой и очень близкой области эпсилон эта непубличность может быть очень даже заметна. Поэтому под "public" в цитате не следует понимать все открытые члены открытых типов, видимые в сторонних сборках. А именно это и подразумевается в MSDN.
+1
я вообще не понимаю какой смысл писать многопоточный код по-разному в зависимости от того, публичный он или нет? писать надо всегда максимально безопасно вне зависимости от purposes.
Здравствуйте, Константин Л., Вы писали:
КЛ>лочась на объект, для этого не предназначенный, ты повышаешь энтропию. объекты синхронизации это не лишние сущности. я предпочитаю заводить readonly object и спать спокойно.
Любой объект предназначен для лока. Энтропия системы остаётся постоянно. А вот добавляя объекты-локеры, ты как раз повышаешь энтропию, ко всему прочему ещё и заставляя поддерживающих твой код быть в курсе того, что для безопасного доступа к объекту Х надо лочиться на объекте Y. Эти объекты никак не связаны друг с другом, а посему саппортерами нужно будет разбираться во всём коде, чтобы увидеть эту связь. В то время как знание о том, что для обеспечения синхронизированного доступа к объекту нужно на нём залочиться, даётся MSDN'ом и всеми книжками по языку и библиотеке, так что мы вправе принять наличие этого знания как данность.
Здравствуйте, _FRED_, Вы писали:
K>>А что кроме public является "видимым где-то снаружи"?
_FR>Как минимум, то, что называется internal.
K>>Снаружи чего кстати?
_FR>Снаружи — означает "извне". Чего именно — да чего угодно, никаких не соответствий не вижу.
_FR>Например, снаружи вложенного private-класса видны его public-члены, но более "снаружи" уже нет. Попадают ли такие public-члены под термин "public", используемый в гайдлайнах? Чаще всего, нет. Но в некоторой узкой и очень близкой области эпсилон эта непубличность может быть очень даже заметна. Поэтому под "public" в цитате не следует понимать все открытые члены открытых типов, видимые в сторонних сборках. А именно это и подразумевается в MSDN.
Под "публичностью" в процитированной мною (да и тобой) статье подразумевается "доступность из кода, который использует ваш класс и при этом неподконтролен вам". По-моему достаточно чёткое определение, и под него чаще всего попадают именно public-члены.
Здравствуйте, koandrew, Вы писали:
K>Здравствуйте, Константин Л., Вы писали:
КЛ>>лочась на объект, для этого не предназначенный, ты повышаешь энтропию. объекты синхронизации это не лишние сущности. я предпочитаю заводить readonly object и спать спокойно.
K>Любой объект предназначен для лока.
случайность и сахар. я бы его убрал, кстати
K>Энтропия системы остаётся постоянно.
ну уж нет
K>А вот добавляя объекты-локеры, ты как раз повышаешь энтропию, ко всему прочему ещё и заставляя поддерживающих твой код быть в курсе того, что для K>безопасного доступа к объекту Х надо лочиться на объекте Y.
да, еще имена переменным обычно дают отличные от apsidlasjdhjy. черт,, это все вообще не проблема
K>Эти объекты никак не связаны друг с другом, а посему саппортерами нужно будет разбираться во всём коде, чтобы увидеть эту связь.
да, в таком коде нужно разбираться неделями (псевдокод):
readonly HashSet<long> InProgress = new HashSet<long>();
readonly object InProgressSync = new object();
bool SetInProgress(long id)
{
lock (InProgressSync)
{
if (InProgress.Contains(id))
return false;
InProgress.Add(id);
return true;
}
}
с чем тут надо разбираться?
K>В то время как знание о том, что для обеспечения синхронизированного доступа к объекту нужно на нём залочиться, даётся MSDN'ом и всеми K>книжками по языку и библиотеке, так что мы вправе принять наличие этого знания как данность.
частный случай. обычно лочат код, а не объекты. лочить объекты дурной тон. лочить нужно код
Здравствуйте, koandrew, Вы писали:
_FR>>Чем потокобезопастность нашего кода, в случае использования специального объекта синхронизации будет отличаться? А то, что SRP нарушается видно очень хорошо: при необходимости реализации другого сценария потокобезопастности может потребоваться синхронизироваться по другому объекту. Если одна синхронизация делается на самом неком объекте, а другая — на объекте сбоку, то возникает вопрос — почему по сути одно и то же реализовано по-разному?
K>SRP не про то, что нельзя один и тот же класс использовать для разных целей, он про то, что конкретный экземпляр класса нужно использовать для одной цели. Если определить цель как "потокобезопасная коллекция", то всё встаёт на свои места.
Если говорить такой о задаче класса, как "потокобезопастная коллекция", то использование lock(внутреннее хранилище) — это отвратительный дизайн. Кстати, очень хороший пример, что бы объяснить почему.
Итак, у нас есть задача сделать потокобезопастную коллекцию.
В обсуждаемом вопросе у нас есть два пути: послушаться меня и завести отдельно поле для синхронизации и послушаться чего-то ещё и лочится, не заморачиваясь со специальным полем, на имеющееся поле внутреннего хранилища. Работать два варианта буду одинаково. Прекрасно.
Теперь вспомним, о чём я предупреждал и посмотрим, что в [интерфейсе] нашей коллекции можно улучшить. Казалось бы — ничего? Коллекция она и есть коллекция и со времён первого фреймворка принципиально не менялась? Ан нет. Есть одно отличие, связанное как раз с многопоточностью: из коллекции ушло свойство SyncRoot. Ушло потому, что во многих сценариях требуется извне задать коллекции объект, по которому требуется синхронизировать обращение к внутреннему хранилищу.
Именно из высказанных мной соображений в одном из предыдущих ответов видно, что послушай вы меня, рефактори и изменять сделанную вами коллекцию было бы гораздо проще, достаточно поменять инициализацию поля синхронизации с new object() на присваение некоего пользователького объекта, переданного в конструктор. Пойди вы по предлагаемому вами пути, вам пришлось бы изменить весь код синхронизации. Не сильно, да. Но весь.
Далее, можем добавить нашей коллекции возможность принимать извне не только объект синхронизации, но и хранилище, в которое синхронно будут записываться данные. Синхронизироваться по такому, переданному извне объекту так же уже не хорошо.
Так вот моё предложение как раз способствует написанию такого кода, который будет дешевле всего поддерживать, потому что в нём нет вынужденных, не обязательных связей между сущностями, ибо каждая такая связь -гвоздь в крышку гроба того, что вы делаете.
K>Вообще же в реальности я обычно в таком случае использую потокобезопасные агрегаты коллекций, которые обеспечивают потокобезопасность внутри себя, позволяя освободить внешний код то мусора, вызванного необходимостью синхронизации.
Что есть агрегат коллекции? Вообще, "потокобезопастная коллекция" сама в себе очень не нужна. Потокобезопастными имеет смысл делать не столько объекты, сколько операции, сценарии работы, более общие, чем "добавить сюда элемент".
Но мы же тут не о подходе, а о способе реализации маленькой частички обеспечения синхронности, которая, однако, используется довольно часто.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, koandrew, Вы писали:
K>>>А что кроме public является "видимым где-то снаружи"? _FR>>Как минимум, то, что называется internal. K>>>Снаружи чего кстати? _FR>>Снаружи — означает "извне". Чего именно — да чего угодно, никаких не соответствий не вижу. _FR>>Например, снаружи вложенного private-класса видны его public-члены, но более "снаружи" уже нет. Попадают ли такие public-члены под термин "public", используемый в гайдлайнах? Чаще всего, нет. Но в некоторой узкой и очень близкой области эпсилон эта непубличность может быть очень даже заметна. Поэтому под "public" в цитате не следует понимать все открытые члены открытых типов, видимые в сторонних сборках. А именно это и подразумевается в MSDN.
K>Под "публичностью" в процитированной мною (да и тобой) статье подразумевается "доступность из кода, который использует ваш класс и при этом неподконтролен вам". По-моему достаточно чёткое определение, и под него чаще всего попадают именно public-члены.
Я опять же не знаю, что такое "неподконтролен вам". И почему это "подконтрольный мне" код должен делать более предлоложений о работе некоего кода Х чем другой код?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, koandrew, Вы писали:
K>SRP не про то, что нельзя один и тот же класс использовать для разных целей, он про то, что конкретный экземпляр класса нужно использовать для одной цели.
Неверное опеределение. Классы могут быть классами-состояния, и классами-поведения. Лочат собственно доступ к ресурсу или набору ресурсов, то есть классу состояния. А он уже используется для разных целей. Поэтому решение как лочить должно лежать на объектах бизнес-логики.
K>Если определить цель как "потокобезопасная коллекция", то всё встаёт на свои места.
Две "потокобезопасных коллекции" уже не являются "потокобезопасными". Сама коллекция может быть потокобезопасна только при атомарных операциях.
Здравствуйте, _FRED_, Вы писали:
_FR>Я опять же не знаю, что такое "неподконтролен вам". "Неподконтрольный вам" == "написанный и поддерживаемый не вами (не вашим тимом/компанией)". _FR>И почему это "подконтрольный мне" код должен делать более предлоложений о работе некоего кода Х чем другой код?
Не должен, но часто делает
Здравствуйте, koandrew, Вы писали:
_FR>>Я опять же не знаю, что такое "неподконтролен вам". "Неподконтрольный вам" == "написанный и поддерживаемый не вами (не вашим тимом/компанией)". _FR>>И почему это "подконтрольный мне" код должен делать более предлоложений о работе некоего кода Х чем другой код? K>Не должен, но часто делает
Делает, не поспоришь
Вопрос в том, должен ли ИМХО, не должен. Гораздо меньше мусора и безобразия получается, если не делить код на "наш"/"ваш", "внешний"/"внутренний". ИМХО, это всё оправдания творческой и производственной импотенции.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Lexey, Вы писали:
L>У Joe Duffy в блогах было неплохое сравнение реализаций разных ReaderWriter'ов, критической секции и спинлоков. Вывод довольно забавный: readerwriter'ы в случае частой записи прилично сливают обычным критическим секциям и спинлокам.
ReaderWriterLockSlim это и есть спинлок.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476 on Windows 7 6.1.7600.0>>
Здравствуйте, koandrew, Вы писали:
K>SRP не про то, что нельзя один и тот же класс использовать для разных целей, он про то, что конкретный экземпляр класса нужно использовать для одной цели.
Сам придумал? SRP предназначен для декомпозиции предметной области на сущности языка программирования. Экземпляры тут вообще не причем.
... << RSDN@Home 1.2.0 alpha 4 rev. 1476 on Windows 7 6.1.7600.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Сам придумал? SRP предназначен для декомпозиции предметной области на сущности языка программирования. Экземпляры тут вообще не причем.