|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
В одном потоке запрашиваю данные из сервиса Код: c# 1. 2. 3. 4. 5. 6.
А в другом потоке использую объект results тоже в блокировке с _locker. По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results. Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2015, 09:14 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Alexey2112В одном потоке запрашиваю данные из сервиса Код: c# 1. 2. 3. 4. 5. 6.
А в другом потоке использую объект results тоже в блокировке с _locker. По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results. Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет? блокировка накладывается на объект _locker, им ты все синхронизируешь. причем тут вообще присвоение? Может тебе нужен double check lock? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 00:19 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
netivanAlexey2112В одном потоке запрашиваю данные из сервиса Код: c# 1. 2. 3. 4. 5. 6.
А в другом потоке использую объект results тоже в блокировке с _locker. По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results. Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет? блокировка накладывается на объект _locker, им ты все синхронизируешь. причем тут вообще присвоение? Может тебе нужен double check lock? Блокировка накладывается на объекты, что в блоке lock. Какой смысл блокировать _locker - это просто самый маленький объект типа object. Я не знаю, зачем они так сделали - пишут, что среда выполнения "фокусируется" на нём. По мне так этот _locker - это просто метка, чтобы помечать разные части кода как зависящие от одной блокировки. Я присвоение блокирую, потому что объект results в другом месте использую - читаю из него данные в другом потоке. Поэтому либо читать, либо переприсваивать. Поэтому и блокировка. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 04:30 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Ну я и спрашиваю, правильно ли я понимаю, как будет происходить процесс - в первом сообщении написал. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 04:30 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Alexey2112, Нужен код обращения к results тогда ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 10:34 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
netivanAlexey2112, Нужен код обращения к results тогда Код вида - вытаскиваем данные из объекта Results и присваиваем их другим объектам. Всё - под локом _locker. Ну т. е. примерно так Код: c# 1. 2. 3. 4. 5. 6. 7.
и т. д. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 13:54 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Alexey2112По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results. Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет? Нет, неправильно. Конструкция lock попытается получить блокировку на объекте _locker. Если он занят, то она будет ждать освобождения. Для того чтобы дело происходило как ты описываешь код нужно записать так: Код: c# 1. 2. 3. 4. 5.
Плюс я бы объявил results как volatile; ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 14:25 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
bazileAlexey2112По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results. Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет? Нет, неправильно. Конструкция lock попытается получить блокировку на объекте _locker. Если он занят, то она будет ждать освобождения. Для того чтобы дело происходило как ты описываешь код нужно записать так: Код: c# 1. 2. 3. 4. 5.
Вот, спасибо. Тоже сначала подумал про временную переменную, но потом решил, что всё же из сервиса можно будет получить данные даже на блокировке. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 14:40 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Alexey2112но потом решил, что всё же из сервиса можно будет получить данные даже на блокировке. Сервис здесь ни при чем. Логика работы lock() не меняется в зависимости от кода внутри. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 14:51 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
bazileПлюс я бы объявил results как volatile; Нет, сценарий немного не тот. Целостность results должна быть. Т. е. получил от сервиса объект results - пока всь его не прочитаю, другой такой же объект от сервиса получать нельзя. У меня два основных сценария рассматривалось. 1. В одном потоке опрашивать сервис часто и каждый результат складывать в коллекцию на клиенте. Другим потоком брать самый новый результат из коллекции и выводить его в UI. Это потому, что отрисовка UI у меня могла занимать больше времени, чем получение очередного results (много графиков и прочего, а на WPF с производительностью не густо). Т. е. всего 2 потока, но при этом без блокировок - т. к. коллекция, в которую складываются результаты, работает по сценарию producer-consumer, где один поток только кидает в неё данные, а другой только берёт. 2. Получаю данные из сервиса, вывожу их в UI (в потоке UI, через Dispatcher). Пока не выведу все полученные данные, новые из сервиса не запрашиваю. Тут тоже два потока, но через блокировку - т. е. тот вариант, что я в начале спрашивал - т. к. нет буферной коллекции результатов. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 14:54 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
bazileAlexey2112но потом решил, что всё же из сервиса можно будет получить данные даже на блокировке. Сервис здесь ни при чем. Логика работы lock() не меняется в зависимости от кода внутри. Согласен. Просто я неправильно понимал логику работы lock. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 14:54 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Alexey2112Нет, сценарий немного не тот. По моему тот. Ты же говоришь что запрос к сервису делается в одном потоке, а обработка (отображение) в другом. Ключевое слово volatalie запретит кеширование значения переменной results в регистрах процессора. То есть второй поток всегда будет заново читать её значение из памяти и гарантированно получит свежее значение. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 15:25 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
bazileAlexey2112Нет, сценарий немного не тот. По моему тот. Ты же говоришь что запрос к сервису делается в одном потоке, а обработка (отображение) в другом. Ключевое слово volatalie запретит кеширование значения переменной results в регистрах процессора. То есть второй поток всегда будет заново читать её значение из памяти и гарантированно получит свежее значение. Мне нужно не свежее, а цельное. Волатильность же даёт возможнось разным потокам писать в переменную? Т. е. пока один поток будет читать одну часть results, другой будет перезаписывать свежими данными другую его часть. Этого мне не надо - все результаты в results зависимы друг от друга и актульны на конкретный момент времени. По-отдельности обновлять их нельзя. Поэтому либо кешировать (буферизовать) их в свою коллекцию результатов, либо блокировать одну и ту же переменную результатов. Я пока только два таких основных способа вижу. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 15:43 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Alexey2112bazileпропущено... По моему тот. Ты же говоришь что запрос к сервису делается в одном потоке, а обработка (отображение) в другом. Ключевое слово volatalie запретит кеширование значения переменной results в регистрах процессора. То есть второй поток всегда будет заново читать её значение из памяти и гарантированно получит свежее значение. Мне нужно не свежее, а цельное. Волатильность же даёт возможнось разным потокам писать в переменную? Т. е. пока один поток будет читать одну часть results, другой будет перезаписывать свежими данными другую его часть. Этого мне не надо - все результаты в results зависимы друг от друга и актульны на конкретный момент времени. По-отдельности обновлять их нельзя. Поэтому либо кешировать (буферизовать) их в свою коллекцию результатов, либо блокировать одну и ту же переменную результатов. Я пока только два таких основных способа вижу. Если есть ещё варианты - с удовольствием послушаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 15:44 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Alexey2112bazileпропущено... По моему тот. Ты же говоришь что запрос к сервису делается в одном потоке, а обработка (отображение) в другом. Ключевое слово volatalie запретит кеширование значения переменной results в регистрах процессора. То есть второй поток всегда будет заново читать её значение из памяти и гарантированно получит свежее значение. Мне нужно не свежее, а цельное. Волатильность же даёт возможнось разным потокам писать в переменную? Т. е. пока один поток будет читать одну часть results, другой будет перезаписывать свежими данными другую его часть. Этого мне не надо - все результаты в results зависимы друг от друга и актульны на конкретный момент времени. По-отдельности обновлять их нельзя. Поэтому либо кешировать (буферизовать) их в свою коллекцию результатов, либо блокировать одну и ту же переменную результатов. Я пока только два таких основных способа вижу. тогда варианта два: 1. любое обращение (чтение) к коллекции блокировать Код: c# 1. 2. 3. 4. 5. 6. 7.
2. Если при получении данных дать чтение не хотите, то делайте как временную - как показали выше. 3. Посмотрите ReaderWriterLockSlim https://msdn.microsoft.com/ru-ru/library/system.threading.readerwriterlockslim(v=vs.110).aspx ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 16:55 |
|
lock при вызове метода сервиса - можно?
|
|||
---|---|---|---|
#18+
Alexey2112Волатильность же даёт возможнось разным потокам писать в переменную? Потоки и так имеют эту возможность т.к. выполняются в одном процессе т.е. делят общее адресное пространство. Volatile добавляет т.н. read/write fence. Alexey2112Т. е. пока один поток будет читать одну часть results, другой будет перезаписывать свежими данными другую его часть. Если Results это ссылочный тип, то этого не произойдет. Метод GetResults() возвращает ссылку на целостное новое значение в памяти. Затем адрес записывается в поле класса. Это атомарная операция. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.07.2015, 17:08 |
|
|
start [/forum/topic.php?fid=19&msg=39017693&tid=1396863]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
57ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
46ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 165ms |
0 / 0 |