powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Насчёт синхронизируемого объекта - lock(synchObject)
32 сообщений из 32, показаны все 2 страниц
Насчёт синхронизируемого объекта - lock(synchObject)
    #39127998
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прочитал у Альбахари , что это обычно приватный объект:

авторThe synchronizing object is typically private (because this helps to encapsulate the locking logic)

Т. е. он разбирает какой-то конкретный случай, когда логика работы с многопоточными данными вся в одном классе инкапсулирована. А что, если мне эти данные надо давать использовать многим другим классам - т. е. сделать их публичными?

Например, у меня схема такая:

класс, который что-то делает (считает, например) - расчётный класс Calc;

класс, который хранит результаты и выводит их на экран:

Код: c#
1.
2.
3.
4.
class Result
{
    public List<double> ResultValues { get; set; }
}



Свойство ResultValues должно иметь многопоточный доступ - Calc постоянно пишет в это свойство, а Result постоянно читает из него и показывает результаты. Проблема в том, что ResultValues - постоянно обновляет свои данные по мере расчёта. При этом по мере расчёта надо показывать промежуточные результаты. Т. е. нужно как-то синхронизировать ResultValues между классами Calc и Result. А поскольку ResultValues это публичное свойство, то мне приходится придумывать некий синхронизирующий объект, который надо шарить между этими двумя классами. Я делаю это так - создаю класс приложения, в который помещаю объекты Calc, Results и синхронизирующий объект. Таким образом я могу расшарить один и тот же синхронизирующий объект между Calc и Result - передавать его через конструкторы этих классов или прямо в те их методы, который используют свойство ResultValues. Т. е. моя схема отличается от того, что говорит Альбахари, что логика синхронизации должна быть инкапсулирована в одном классе.

Я делаю всё правильно, или можно придумать схему лучше для моего случая?
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128001
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что, если сделать само свойство ResultValues синхронизируемым объектом, и везде, где используется это свойство - неважно, в своём классе, в котором объявлено это свойство, или в чужих - писать lock(ResultValues)?

Был ещё вариант, сделать это свойство приватным, но добавить публинчые обёртки над этим свойством, типа GetResultValues, AddNewValuesToResult и т. п., которые бы под локом делали бы свою работу. Но показалось, что это слишком мудрёный вариант, который мало что даёт.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128002
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987А что, если сделать само свойство ResultValues синхронизируемым объектом, и везде, где используется это свойство - неважно, в своём классе, в котором объявлено это свойство, или в чужих - писать lock(ResultValues)?

Был ещё вариант, сделать это свойство приватным, но добавить публинчые обёртки над этим свойством, типа GetResultValues, AddNewValuesToResult и т. п., которые бы под локом делали бы свою работу. Но показалось, что это слишком мудрёный вариант, который мало что даёт.
Первый вариант плох тем, что невозможно заставить или как-то сообщить пользователю класса Result, что с ResultValues надо работать именно так. А второй хорош тем, что я заставляю пользователя ResultValues работать с ним только через методы, которые уже внутри используют блокировку.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128004
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возьми ConcurrentBag это тот же лист, только потокобезопасный.
Хотя тут очередь больше подойдет ConcurrentQueue

Все потокобезопасные классы
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128013
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВозьми ConcurrentBag это тот же лист, только потокобезопасный.
Хотя тут очередь больше подойдет ConcurrentQueue

Все потокобезопасные классы
Мне кажется, что потокобезопасные классы тут не очень подходят. Я уточню желательный сценарий использования ResultValues:

1) расчёт у меня работает циклически - приходит новая порция данных и класс Calc делает итерацию расчёта;

2) при каждой итерации класс Calc полностью обновляет ResultValues;

3) после каждой итерации класс Result считывает "снимок" ResultValues и выводит его на экран. Если не получается после каждой итерации считать, можно пропускать - главное, чтобы Result не считывал значения из ResultValues посередение заполнения ResultValues классом Calc.

В реальности я это реализую так - класс Calc молотит в бесконечном цикле while(true), ожидая новых данных и делая паузы посредством Thread.Sleep (думаю в будущем заменить на какой-нибудь SpinLock или Wait/Pulse, но пока так), класс Result делает то же самое - while(true) и Thread.Sleep. И оба класс работают с ResultValues через расшаренный синхронизирующий объект с помощью lock(synchObject).
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128014
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т. е. из-за вот этого

AlexUser9872) при каждой итерации класс Calc полностью обновляет ResultValues;

3) после каждой итерации класс Result считывает "снимок" ResultValues

я не вижу смысла в потокобезопасных коллекциях в моём случае.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128016
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987В реальности я это реализую так - класс Calc молотит в бесконечном цикле while(true), ожидая новых данных и делая паузы посредством Thread.Sleep (думаю в будущем заменить на какой-нибудь SpinLock или Wait/Pulse, но пока так), класс Result делает то же самое - while(true) и Thread.Sleep. И оба класс работают с ResultValues через расшаренный синхронизирующий объект с помощью lock(synchObject).
Да, забыл уточнить, что, естественно, каждый из классов Calc и Result работает в своём потоке. Точнее, в отдельных потоках запускаются методы этих классов, ответственные, соответственно, за расчёт и за вывод результатов.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128028
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser9872) при каждой итерации класс Calc полностью обновляет ResultValues;

... главное, чтобы Result не считывал значения из ResultValues посередение заполнения ResultValues классом Calc.

Тогда генери в Calc новый List и присваивай по окончанию, т.е. так
Код: c#
1.
2.
3.
4.
5.
Calc() {
  var list = new List<double>();
  ... считаем, заполняем list
  ResultValues = list;
}


И не надо никаких синхронизаций. Можешь AutoResetEvent добавить для пробуждения Result
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128031
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИ не надо никаких синхронизаций. Можешь AutoResetEvent добавить для пробуждения Result
Почему не надо? А если класс Result перебирает элементы ResultValues, а в этом время класс Calc обновляет/подменяет ResultValues?

Т. е. в моём случае он обновляет данные в ResultValues, а в вашем - подменяет всю коллекцию новым объектом ResultValues. Но результат всё равно один - изменение коллекции ResultValues во время её перебора другим потоком.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128033
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я ещё думал создать для ResultValues коллекцию

List<List<double>> ResultValuesList

И чтобы после каждого расчёта Calc добавлял в ResultValuesList результаты, а Result бы забирал только последний на текущий момент элемент - т. е. последний результат. Ну и после каждого такого забора удаление из ResultValuesList всех предыдущих коллекций результатов, чтобы память не занимали. Как такой вариант? Тогда точно синхронизаций и блокировок не понадобится.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128043
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987Dima TИ не надо никаких синхронизаций. Можешь AutoResetEvent добавить для пробуждения Result
Почему не надо? А если класс Result перебирает элементы ResultValues, а в этом время класс Calc обновляет/подменяет ResultValues?

Т. е. в моём случае он обновляет данные в ResultValues, а в вашем - подменяет всю коллекцию новым объектом ResultValues. Но результат всё равно один - изменение коллекции ResultValues во время её перебора другим потоком.
Результаты разные: в твоем случае объект один, в моем случае два разных, поэтому синхронизация не нужна.
Немного не дописал, чтобы в Result не сглючило лучше так
Код: c#
1.
2.
3.
4.
Result() {
   var list = ResultValues;
   ... выводим из list
}



Т.е. Calc() создал объект, наполнил, сохранил ссылку на объект в ResultValues и больше с объектом не работает. Result() взял ссылку из ResultValues и вывел. Точка пересечения Calc() и Result() только в передаче ссылки через ResultValues. Эта операция атомарная, т.е. не требует доп.синхронизаций (если путаю поправьте).
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128045
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987В реальности я это реализую так - класс Calc молотит в бесконечном цикле while(true), ожидая новых данных и делая паузы посредством Thread.Sleep
Черезжопная реализация. Sleep() - вставка тормоза чтоб проц в холостую не гонять. Разбирайся с источником данных, чтобы он будил Calc при появлении данных.
AlexUser987(думаю в будущем заменить на какой-нибудь SpinLock или Wait/Pulse, но пока так), класс Result делает то же самое - while(true) и Thread.Sleep. И оба класс работают с ResultValues через расшаренный синхронизирующий объект с помощью lock(synchObject).
Используй AutoResetEvent: Result висит на эвенте, Calc как посчитал и сохранил сбрасывает эвент, Result просыпается, выводит и дальше висит на эвенте.

PS Почитай Дж. Рихтер CLR via C# . Часть V. Многопоточность.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128462
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TAlexUser987пропущено...

Почему не надо? А если класс Result перебирает элементы ResultValues, а в этом время класс Calc обновляет/подменяет ResultValues?

Т. е. в моём случае он обновляет данные в ResultValues, а в вашем - подменяет всю коллекцию новым объектом ResultValues. Но результат всё равно один - изменение коллекции ResultValues во время её перебора другим потоком.
Результаты разные: в твоем случае объект один, в моем случае два разных, поэтому синхронизация не нужна.
Немного не дописал, чтобы в Result не сглючило лучше так
Код: c#
1.
2.
3.
4.
Result() {
   var list = ResultValues;
   ... выводим из list
}



Т.е. Calc() создал объект, наполнил, сохранил ссылку на объект в ResultValues и больше с объектом не работает. Result() взял ссылку из ResultValues и вывел. Точка пересечения Calc() и Result() только в передаче ссылки через ResultValues. Эта операция атомарная, т.е. не требует доп.синхронизаций (если путаю поправьте).
Да, вы правы - я упустил из виду

var list = new List<double>();

в классе Calc.

Спасибо и за другие советы - посмотрю.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128463
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987var list = new List<double>();
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128570
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не вчитывался особо в суть проблемы,уверен, что задачу можно решить проще и по другому, но ответы на вопросы на всякий случай.

AlexUser987А что, если сделать само свойство ResultValues синхронизируемым объектом, и везде, где используется это свойство - неважно, в своём классе, в котором объявлено это свойство, или в чужих - писать lock(ResultValues)?
SyncRoot . Как раз тот же принцип. Все уже придумано до нас.

AlexUser987Был ещё вариант, сделать это свойство приватным, но добавить публинчые обёртки над этим свойством, типа GetResultValues, AddNewValuesToResult и т. п
Делается обычно так. В класс добавляются 2 метода. Например, Lock и UnLock. В Lock добавляем Monitor.Enter, в UnLock сами догадаетесь?

Применение:

Код: plaintext
1.
2.
3.
4.
5.
6.
MyObject.Lock();
try {
  ...
}
finally {
  MyObject.UnLock();
}


Но ценность таких вариантов достаточно сомнительна. В первую очередь нужно смотреть на возможность lock-free работы.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128720
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79Не вчитывался особо в суть проблемы,уверен, что задачу можно решить проще и по другому, но ответы на вопросы на всякий случай.

AlexUser987А что, если сделать само свойство ResultValues синхронизируемым объектом, и везде, где используется это свойство - неважно, в своём классе, в котором объявлено это свойство, или в чужих - писать lock(ResultValues)?
SyncRoot . Как раз тот же принцип. Все уже придумано до нас.

AlexUser987Был ещё вариант, сделать это свойство приватным, но добавить публинчые обёртки над этим свойством, типа GetResultValues, AddNewValuesToResult и т. п
Делается обычно так. В класс добавляются 2 метода. Например, Lock и UnLock. В Lock добавляем Monitor.Enter, в UnLock сами догадаетесь?

Применение:

Код: plaintext
1.
2.
3.
4.
5.
6.
MyObject.Lock();
try {
  ...
}
finally {
  MyObject.UnLock();
}


Но ценность таких вариантов достаточно сомнительна. В первую очередь нужно смотреть на возможность lock-free работы.
Про синк рут спасибо. Про дальнейшее - что-то сомнительным выглядит. Как заставить пользователя класса пользоваться моим классом именно по такой сложной схеме? С таким же успехом можно заставить его самостоятельно локать свойства-коллекции этого класса - т. е. никак. Разве что в комментариях или документации к классу очень сильно попросить, что делать надо именно так, а не иначе, а если нет, то будет упс.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128733
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про синк рут полезная вещь. Просто на самом деле я упростил свой пример и у меня по смыслу не одна коллекция пишется-читается, а несколько, поэтому выделить специальный объект под синхронизацию ВСЕГО этого дела в виде "атомарной" операции под локом кажется более подходящим.

А вообще, как поступить, если в моём классе Result не просто одна коллекция, которую постоянно целиком обновляет другой класс, а нечто смешанное? Например, у меня вот такая коллеция, как выше описана - т. е. полностью обновляющаяся в каждой итерации расчёта. Потом ещё другая коллеция, которая лишь добавляет очередную пачку рассчитанных данных в конец уже существующих - т. е. пополняющиеся результаты. Плюс ещё просто числа, которые обновляются. И вот весь этот набор надо бы защищить от изменения классом расчёта Calc, пока его класс результатов Result выводит на экран. Тут удобнее всё это под одним общим локом разместить, или как? Или к каждому типу данных свой подход - где-то volatile, где-то из concurrent collection взять, а где-то через lock сделать? Я вот пока реализовал - всё изменения и чтения всех этих разношёрстных результатов поместил под одним общим lock.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128865
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987Я вот пока реализовал - всё изменения и чтения всех этих разношёрстных результатов поместил под одним общим lock.
Работает? Проблем по скорости нет? Никто не жалуется? Значит, нормально.
Сделайте хоть как то, чтобы работало, потом рефакторьте код.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128888
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79AlexUser987Я вот пока реализовал - всё изменения и чтения всех этих разношёрстных результатов поместил под одним общим lock.
Работает? Проблем по скорости нет? Никто не жалуется? Значит, нормально.
Сделайте хоть как то, чтобы работало, потом рефакторьте код.
Да давно уже работает. Я вот откопал своё старьё и думаю, как получше сделать. Т. к. скоро что-то подобное придётся снова делать - думаю, не повторять же то же самое. Может, получше варианты есть. Так сказать, общие подходы. Тот же Альбахари про это, вроде, ничего не пишет. В этом вашем Рихтере есть что подобное?
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128937
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТочка пересечения Calc() и Result() только в передаче ссылки через ResultValues. Эта операция атомарная, т.е. не требует доп.синхронизаций (если путаю поправьте).
ставьте volatile и должно быть норм.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128943
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987В этом вашем Рихтере есть что подобное?
Почитай, хуже не будет. ХЗ есть или нет, слишком уж абстрактно у тебя задача сформулирована. По крайней мере узнаешь о всех возможных альтернативах решения твоей задачи.

Как выше упомянули надо в сторону lock-free идти (в моих примерах оно самое).
Закон Амдала никто не отменял, поэтому чем больше синхронизируешься, тем меньше пользы от распараллеливания.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39128951
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987,

А каждая порция данных от Calc должна быть обработана Result?
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129014
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79AlexUser987,

А каждая порция данных от Calc должна быть обработана Result?
Нет.

Result делает слепок с набора результатов и потом сразу "освобождает" (в смысле, что перестаёт использовать - считывать значения там и прочее) этот набор, чтобы Calc дальше мог в него писать. В момент создания слепка я и применяю блокировку через lock. После создания слепка Result неспешно выводит результаты из этого слепка на экран. Неспешно в том смысле, что копирование данных в слепок происходит гораздо быстрее, чем отображение на экране. В этом время Calc под локом пишет в набор результатов, которые только что освободил Result. Обычно у меня получается, что Calc может множество итераций расчёта провести на одну итерацию вывода результатов - т. е. он несколько раз перезапишет набор результатов. Поэтому Result берёт слепок всегда с последней версии результатов. Это нужно, чтобы результаты отображались в реальном времени - с приемлемой задержкой по отношению к поступающим данным.

Задачи показать вывод именно по всем результатам у меня пока нет. Если будет - переделаю, чтобы результаты накапливались в коллекции.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129023
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T Закон Амдала
Кстати, он показывает, что технологической сингулярности не будет. Даже если доведут до ума квантовые компьютеры. Но будет некоторое приближение к ней. Довольно близкое и болезненное.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129040
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987,

Элементов в наборе данных много? десятки? сотни? тысячи? миллионы?
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129078
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987Result делает слепок с набора результатов и потом сразу "освобождает" (в смысле, что перестаёт использовать - считывать значения там и прочее) этот набор, чтобы Calc дальше мог в него писать. В момент создания слепка я и применяю блокировку через lock.
ИМХУ тут обратно надо. Calc делает слепок и отдает его, тогда блокировок не надо. Опять же вопрос как часто это надо? Например если Result() обрабатывает только каждый тысячный слепок, то будет лишний тормоз.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129154
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИМХУ тут обратно надо. Calc делает слепок и отдает его, тогда блокировок не надо.
Т. е. тот, кто считает, тот же и слепок делает?

Да в принципе не важно, по-моему, кто там чего делает - Calc, Result или ещё какие сущности. Я просто примерно раскидал задачи по классам. Можно всё и в один класс запихать, а можно и ещё разделить.

Или я вас не понял.

Важно, что есть одновременный доступ к результатам расчёта из разных потоков. Потому что вот эти вещи

1) расчёт,
2) сохранение результатов в переменных в ОЗУ в процессе расчёта,
3) создание слепка из результатов,
4) вывод слепка результатов на экран

должны быть как можно больше независимы друг от друга.

У меня раньше было без слепка. Т. е. на протяжении всего расчёта данные писались в набор результатов под локом, и класс Result не мог получить к ним доступ, чтобы вывести результаты на экран. Когда же получал, то выводил именно результаты (пункт 2), а не слепок.

Расчёт длится гораздо дольше создания слепка результатов. Поэтому, когда я ввёл слепок, я смог больше распараллелить всю работу, т. к. теперь, фактически, локи работали только в моменты создания слепка.

Вообще без локов, на мой взгляд - только если накапливать весь набор результатов в коллекцию наборов результатов. И потом Result будет брать самый последний добавленный набор результатов (банально проверяем свойство Count без всяких локов, и берём текущее последнее значение). Ну, я уже об этом раньше писал.

Я так думаю.

Arm79AlexUser987,

Элементов в наборе данных много? десятки? сотни? тысячи? миллионы?
В смысле элементов? Число коллекций, объектов, значений? Или вплоть до числа элементов в каждой коллекции? Если первое, то 20-100.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129258
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987В смысле элементов? Число коллекций, объектов, значений? Или вплоть до числа элементов в каждой коллекции? Если первое, то 20-100.
Коллекций до 100? А в каждой коллекции сколько элементов?
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129327
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arm79AlexUser987В смысле элементов? Число коллекций, объектов, значений? Или вплоть до числа элементов в каждой коллекции? Если первое, то 20-100.
Коллекций до 100? А в каждой коллекции сколько элементов?
Нет. Коллекций штук 10-20. Плюс несколько десятков строковых и числовых переменных, собранных в разные объекты.

Коллекции есть разные. Есть, где в принципе 1-10 элементов и больше навряд ли будет. А есть, где 100-10000. Да и я сейчас стараюсь переработать, чтобы не более 2000-3000 было.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129338
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexUser987Dima TИМХУ тут обратно надо. Calc делает слепок и отдает его, тогда блокировок не надо.
Т. е. тот, кто считает, тот же и слепок делает?
Да

AlexUser987Да в принципе не важно, по-моему, кто там чего делает - Calc, Result или ещё какие сущности. Я просто примерно раскидал задачи по классам. Можно всё и в один класс запихать, а можно и ещё разделить.

Или я вас не понял.

Важно, что есть одновременный доступ к результатам расчёта из разных потоков. Потому что вот эти вещи

1) расчёт,
2) сохранение результатов в переменных в ОЗУ в процессе расчёта,
3) создание слепка из результатов,
4) вывод слепка результатов на экран

должны быть как можно больше независимы друг от друга.
Определись уже важно или нет.
Если слепок делает Result то он должен остановить Calc, следовательно Calc должен регулярно проверять блокировку, что тоже ресурсы потребляет.
Если слепок делает Calc, то ему не надо проверять блокировки, он просто сделал новый слепок, отдал на него ссылку и больше этот слепок не трогает. Чтобы отдать ссылку синхронизации не надо.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129879
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЕсли слепок делает Calc, то ему не надо проверять блокировки, он просто сделал новый слепок, отдал на него ссылку и больше этот слепок не трогает. Чтобы отдать ссылку синхронизации не надо.
Да, не надо. Просто, по-вашему, Calc будет после каждой итерации расчёта слепки делать в том же потоке, вместо того, чтобы заниматься новой итерацией. Я вас правильно понял?

У меня логика такая, что Result сам запрашивает/делает слепок. Т. е. Calc должен только молотить расчёт. В принципе, если Result не запросит ни разу результат для отображения, то Calc так и домолотит до конца и оставит в переменных результатов последний вариант результатов. Это я сделал для того, чтобы легко было приспособить всю схему под клиент-сервер. Когда сервер только считает, но не оповещает клиента, что закончилась очередная итерация расчёта. Вместо этого сам клиент запрашивает сервер в цикле и, если новая итерация закончилась, то получает слепок. При этом неважно, какой класс делает слепок на стороне сервера - сам Calc или специально созданный для этого класс. Вот это я имел ввиду, говоря

авторДа в принципе не важно, по-моему, кто там чего делает - Calc, Result или ещё какие сущности

А насчёт этого

авторэти вещи

1) расчёт,
2) сохранение результатов в переменных в ОЗУ в процессе расчёта, (у меня объединено с 1)
3) создание слепка из результатов,
4) вывод слепка результатов на экран

должны быть как можно больше независимы друг от друга.

я имел ввиду по потокам. Т. е. вышеперечисленные пункты должны выполняться в разных потоках. Но при этом код этих пунктов может быть где угодно - хоть в одном классе, хоть в разных - это просто методы классов.

И вот в клиент-серверном варианте я сделал как вы сказали - у меня метод, делающий слепок, находится в классе Calc (исторически сложилось - ещё не разбил свой god-class на части). Класс Result находится на клиенте. Да, в принципе, и в локальном варианте то же самое - просто библиотеку расчёта я перенёс из веб-сервиса на клиент и принцип работы не изменился - Result запрашивает Calc о новых результатов и просит сделать слепок.
...
Рейтинг: 0 / 0
Насчёт синхронизируемого объекта - lock(synchObject)
    #39129880
AlexUser987
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я, наверное, вас запутал. Потому что хотел задать простой вопрос, а реальная ситуация у меня сложнее. Пришлось наворачивать и наворачивать по мере обсуждения. Вобщем, я достаточно просветился, спасибо за помощь.
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Насчёт синхронизируемого объекта - lock(synchObject)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]