forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Общее (http://forum.boolean.name/forumdisplay.php?f=139)
-   -   Правильная организация Server<-> client (http://forum.boolean.name/showthread.php?t=20463)

RegIon 01.11.2016 21:01

Ответ: Правильная организация Server<-> client
 
* async/await, как говорил чувак с какой-то конференции, в WPF (а у меня именно он) после await продолжает выполнение в том же потоке, в котором запущен этот async метод, но это не точно.

* Ну да, async/await - декораторы для генератора кода, а вот реализация (WPF, MVC ) какого-то хрена везде разная, но в WPF работает первый пункт. Наверное связно с тем, что бы не было проблем с UI.

* Про остановку потока знаю, но у меня сейчас не таск, а поток отдельный как раз. Если его не тормозить - огромные нагрузки из-за пустого while фактически.

h1dd3n 01.11.2016 23:06

Ответ: Правильная организация Server<-> client
 
1. Это правда. Это связано с контекстом синхронизации. Каждое приложение реализует свой особенный контекст. Например, тот который в wpf и winforms, при вызове из ui потока, вернет тебя в ui поток. Это нужно для удобства:

// надо что-то откуда-то загрузить
buttonDownload.Enabled = false;
var content = await SomeWebClient.GetContent();
buttonDownload.Enabled = true;

Вот здесь на последней строке будут проблемы если будешь не в ui потоке (манипуляции с ui контролами можно делать только из ui потока). В ASP NET MVC таких ограничений нет, наоборот чем свободнее будет выбор потока, тем лучше масштабируемость. В веб приложениях вообщем-то пофигу в каком потоке что выполняется, там важны только вещи типа HttpContext.Current

2. Надо проверить что в WPF возвращение к тому же потоку происходит во всех потоках, а не только в UI потоке.

3. Но нафига тебе реальный поток? Создай таск а потоками пуская шедулер занимается (он из тредпула возьмет).
Какой такой пустой while?

RegIon 02.11.2016 07:41

Ответ: Правильная организация Server<-> client
 


Временная реализация выглядит так.

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

UPD. Сменил на таску, благо меняется это одной строчкой.

h1dd3n 02.11.2016 19:48

Ответ: Правильная организация Server<-> client
 
Дак в итоге то ты проверил, в WPF если вызвать метод не в UI потоке, то продолжение то где выполнится?

NetProtocol.requestStoping - это твой код? там модификатор volatile есть?

RegIon 02.11.2016 21:18

Ответ: Правильная организация Server<-> client
 
Цитата:

Сообщение от h1dd3n (Сообщение 309670)
Дак в итоге то ты проверил, в WPF если вызвать метод не в UI потоке, то продолжение то где выполнится?

Вот нифига, выкидывает в другой поток и никогда не возвращает в старый, походу только UI возвращается, так что да, async в ручном потоке - плохое дело.

Цитата:

NetProtocol.requestStoping - это твой код? там модификатор volatile есть?
а смысл?, он не меняется в различных потоках, только в одном. И да, его уже нет, сейчас там TaskCancelator.

h1dd3n 02.11.2016 21:33

Ответ: Правильная организация Server<-> client
 
Если это поле используется как минимум в 2-ух потоках (например, в 1 читается, в другом пишется), то лучше сделать его volatile. Если оно к тому же читается многократно, его очень настоятельно рекомендуется сделать volatile.
Дело в том что оптимизирующий компилятор (JIT) может убрать цикл вообще, т.к. видит что там просто доступ к полю (он предположит что значение не меняется в другом потоке). Если отметишь как volatile, ты заставишь компилятор всегда читать из поля данные, то есть запретишь где-либо их кэшировать и т.д.

Цитата:

Вот нифига, выкидывает в другой поток, походу только UI возвращается.
Ну дак и отлично. Возвращается там где SynchronizationContext.Current это DispatcherSynchronizationContext. Контекст синхронизации задается у каждого потока. WPF для потока UI задал соответствующий контекст. У других потоков (которые из тредпула, например) SynchronizationContext.Current == null. Механизм await если видит что контекст синхронизации == null, просто продолжение планирует при помощи TaskScheduler.Current (который, если ты его не менял, скорее всего TaskScheduler.Default). А TashScheduler.Default все планирует на потоки из тредпула.


Часовой пояс GMT +4, время: 16:29.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot