powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / lock при вызове метода сервиса - можно?
16 сообщений из 16, страница 1 из 1
lock при вызове метода сервиса - можно?
    #39015080
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В одном потоке запрашиваю данные из сервиса

Код: c#
1.
2.
3.
4.
5.
6.
Results results;

lock (_locker)
{
	results = calculation.GetResults(); // call service method synchronously
}



А в другом потоке использую объект results тоже в блокировке с _locker.

По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results.

Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет?
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017229
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey2112В одном потоке запрашиваю данные из сервиса

Код: c#
1.
2.
3.
4.
5.
6.
Results results;

lock (_locker)
{
	results = calculation.GetResults(); // call service method synchronously
}



А в другом потоке использую объект results тоже в блокировке с _locker.

По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results.

Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет?
блокировка накладывается на объект _locker, им ты все синхронизируешь. причем тут вообще присвоение?
Может тебе нужен double check lock?
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017260
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanAlexey2112В одном потоке запрашиваю данные из сервиса

Код: c#
1.
2.
3.
4.
5.
6.
Results results;

lock (_locker)
{
	results = calculation.GetResults(); // call service method synchronously
}



А в другом потоке использую объект results тоже в блокировке с _locker.

По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results.

Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет?
блокировка накладывается на объект _locker, им ты все синхронизируешь. причем тут вообще присвоение?
Может тебе нужен double check lock?
Блокировка накладывается на объекты, что в блоке lock. Какой смысл блокировать _locker - это просто самый маленький объект типа object. Я не знаю, зачем они так сделали - пишут, что среда выполнения "фокусируется" на нём. По мне так этот _locker - это просто метка, чтобы помечать разные части кода как зависящие от одной блокировки.

Я присвоение блокирую, потому что объект results в другом месте использую - читаю из него данные в другом потоке. Поэтому либо читать, либо переприсваивать. Поэтому и блокировка.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017261
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну я и спрашиваю, правильно ли я понимаю, как будет происходить процесс - в первом сообщении написал.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017398
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey2112,

Нужен код обращения к results тогда
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017603
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanAlexey2112,

Нужен код обращения к results тогда
Код вида - вытаскиваем данные из объекта Results и присваиваем их другим объектам. Всё - под локом _locker. Ну т. е. примерно так

Код: c#
1.
2.
3.
4.
5.
6.
7.
lock(_locker)
{
    myAnotherResults.Number = results.Number;

    foreach(var a in results.Sequence)
        // do some stuff;
}



и т. д.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017638
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey2112По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results.

Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет?
Нет, неправильно. Конструкция lock попытается получить блокировку на объекте _locker. Если он занят, то она будет ждать освобождения. Для того чтобы дело происходило как ты описываешь код нужно записать так:
Код: c#
1.
2.
3.
4.
5.
Results tempResults = calculation.GetResults();
lock (_locker)
{
	results = tempResults;
}


Плюс я бы объявил results как volatile;
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017664
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileAlexey2112По моему мнению, сначала будет вызван метод службы (синхронно). Он отработает и вернёт результат. Результат будет храниться в стеке до тех пор, пока в другом потоке не разблокируется results, после чего в первом потоке будет присвоение значения из стека объекту results.

Правильно я понимаю? Т. е. вызов метода сервиса не будет ждать разблокировки, а вот присвоение результата - будет?
Нет, неправильно. Конструкция lock попытается получить блокировку на объекте _locker. Если он занят, то она будет ждать освобождения. Для того чтобы дело происходило как ты описываешь код нужно записать так:
Код: c#
1.
2.
3.
4.
5.
Results tempResults = calculation.GetResults();
lock (_locker)
{
	results = tempResults;
}


Вот, спасибо. Тоже сначала подумал про временную переменную, но потом решил, что всё же из сервиса можно будет получить данные даже на блокировке.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017682
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey2112но потом решил, что всё же из сервиса можно будет получить данные даже на блокировке.
Сервис здесь ни при чем. Логика работы lock() не меняется в зависимости от кода внутри.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017692
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileПлюс я бы объявил results как volatile;
Нет, сценарий немного не тот. Целостность results должна быть. Т. е. получил от сервиса объект results - пока всь его не прочитаю, другой такой же объект от сервиса получать нельзя.

У меня два основных сценария рассматривалось.

1. В одном потоке опрашивать сервис часто и каждый результат складывать в коллекцию на клиенте. Другим потоком брать самый новый результат из коллекции и выводить его в UI. Это потому, что отрисовка UI у меня могла занимать больше времени, чем получение очередного results (много графиков и прочего, а на WPF с производительностью не густо). Т. е. всего 2 потока, но при этом без блокировок - т. к. коллекция, в которую складываются результаты, работает по сценарию producer-consumer, где один поток только кидает в неё данные, а другой только берёт.

2. Получаю данные из сервиса, вывожу их в UI (в потоке UI, через Dispatcher). Пока не выведу все полученные данные, новые из сервиса не запрашиваю. Тут тоже два потока, но через блокировку - т. е. тот вариант, что я в начале спрашивал - т. к. нет буферной коллекции результатов.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017693
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileAlexey2112но потом решил, что всё же из сервиса можно будет получить данные даже на блокировке.
Сервис здесь ни при чем. Логика работы lock() не меняется в зависимости от кода внутри.
Согласен. Просто я неправильно понимал логику работы lock.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017748
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey2112Нет, сценарий немного не тот.
По моему тот. Ты же говоришь что запрос к сервису делается в одном потоке, а обработка (отображение) в другом. Ключевое слово volatalie запретит кеширование значения переменной results в регистрах процессора. То есть второй поток всегда будет заново читать её значение из памяти и гарантированно получит свежее значение.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017783
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazileAlexey2112Нет, сценарий немного не тот.
По моему тот. Ты же говоришь что запрос к сервису делается в одном потоке, а обработка (отображение) в другом. Ключевое слово volatalie запретит кеширование значения переменной results в регистрах процессора. То есть второй поток всегда будет заново читать её значение из памяти и гарантированно получит свежее значение.
Мне нужно не свежее, а цельное. Волатильность же даёт возможнось разным потокам писать в переменную? Т. е. пока один поток будет читать одну часть results, другой будет перезаписывать свежими данными другую его часть. Этого мне не надо - все результаты в results зависимы друг от друга и актульны на конкретный момент времени. По-отдельности обновлять их нельзя. Поэтому либо кешировать (буферизовать) их в свою коллекцию результатов, либо блокировать одну и ту же переменную результатов. Я пока только два таких основных способа вижу.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017784
Alexey2112
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey2112bazileпропущено...

По моему тот. Ты же говоришь что запрос к сервису делается в одном потоке, а обработка (отображение) в другом. Ключевое слово volatalie запретит кеширование значения переменной results в регистрах процессора. То есть второй поток всегда будет заново читать её значение из памяти и гарантированно получит свежее значение.
Мне нужно не свежее, а цельное. Волатильность же даёт возможнось разным потокам писать в переменную? Т. е. пока один поток будет читать одну часть results, другой будет перезаписывать свежими данными другую его часть. Этого мне не надо - все результаты в results зависимы друг от друга и актульны на конкретный момент времени. По-отдельности обновлять их нельзя. Поэтому либо кешировать (буферизовать) их в свою коллекцию результатов, либо блокировать одну и ту же переменную результатов. Я пока только два таких основных способа вижу.
Если есть ещё варианты - с удовольствием послушаю.
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017906
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey2112bazileпропущено...

По моему тот. Ты же говоришь что запрос к сервису делается в одном потоке, а обработка (отображение) в другом. Ключевое слово volatalie запретит кеширование значения переменной results в регистрах процессора. То есть второй поток всегда будет заново читать её значение из памяти и гарантированно получит свежее значение.
Мне нужно не свежее, а цельное. Волатильность же даёт возможнось разным потокам писать в переменную? Т. е. пока один поток будет читать одну часть results, другой будет перезаписывать свежими данными другую его часть. Этого мне не надо - все результаты в results зависимы друг от друга и актульны на конкретный момент времени. По-отдельности обновлять их нельзя. Поэтому либо кешировать (буферизовать) их в свою коллекцию результатов, либо блокировать одну и ту же переменную результатов. Я пока только два таких основных способа вижу.
тогда варианта два:
1. любое обращение (чтение) к коллекции блокировать
Код: c#
1.
2.
3.
4.
5.
6.
7.
void DoSomethingWithResults()
{
lock(_syncObject)
{
// DO
}
}


2. Если при получении данных дать чтение не хотите, то делайте как временную - как показали выше.
3. Посмотрите ReaderWriterLockSlim https://msdn.microsoft.com/ru-ru/library/system.threading.readerwriterlockslim(v=vs.110).aspx
...
Рейтинг: 0 / 0
lock при вызове метода сервиса - можно?
    #39017922
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey2112Волатильность же даёт возможнось разным потокам писать в переменную?
Потоки и так имеют эту возможность т.к. выполняются в одном процессе т.е. делят общее адресное пространство. Volatile добавляет т.н. read/write fence.

Alexey2112Т. е. пока один поток будет читать одну часть results, другой будет перезаписывать свежими данными другую его часть.
Если Results это ссылочный тип, то этого не произойдет. Метод GetResults() возвращает ссылку на целостное новое значение в памяти. Затем адрес записывается в поле класса. Это атомарная операция.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / lock при вызове метода сервиса - можно?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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