Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

чего-то я не догоняю...

395  
anly коренной житель04.09.18 20:01
anly
04.09.18 20:01 

Вступление.

Подключили меня к проекту, который уже несколько лет разрабатывается (правда денег пока не приносит, но дело не в этом). Разрабатывается он на си-шарпе (как замена очень старому си-2хплюсовому проекту, который еще на 16-ти битах начинался, но до сих пор живет, с кучей клиентов). Этот новый проект (точнее солюшин) состоит где-то из 350 проектов (половина из которых - юнит тесты).

Проекты между собой коммуницируют только через интерфейсы. Т.е. обычно это пара: проект, который содержит только интерфейсы, и проект который их реализует.

И того получается - 350/2/2 = 87 проектов с реальным кодом. Ну а интерфейсов, понятно, гораздо больше. Ну а функций в каждом интерфейсе - от парочки, до пары десятков.


А теперь суть.

Дали мне задание все функции каждого интерфейса сделать асинхронными. Т.е. чтоб каждая функция возвращала Task.

Причем на данном этапе моя работа сводится к рефакторингу, т.е. чтоб поведение программы не поменялось. А делается это созданием каждому интерфейсу еще одного статического класса который имплементирует для каждой функции extensios (ну там где this интерфейса первый аргумент), а имплементация вызывает интрерфейсную функцию (уже возвращающую Task) и тут же Wait() или Result.

Это все, как мне об\яснили руководители проекта - для будущего.

А пока получается, что каждый вызов любой функции интерфейса создает Task, и тут же ждет ее завершение. Т.е. по сути работает как и раньше - синхронно.


Вот этого я и не догоняю - нафига?!

По моему опыту, плодить Задачи (Task) нужно только если действительно приспичит (т.к. многозадачность затрудняет поддержку кода), а не "на всякий случай, для будущего". И мой прогноз, что 99% чего я переделаю так и останется навсегда работать синхронно.

(я кстати уже практически все сделал, благодаря разработанному алгоритму действий поисков - замен регулярными выражениями).

Я даже митинг согнал, где высказал своё "фе", но руководители сказали - даже Майкрософт в интерфейсах работы с файлами предоставляет асинхронные методы!

Проклят нарушающий межи ближнего своего (Втор.27:17)
#1 
AlexNek патриот04.09.18 22:09
AlexNek
NEW 04.09.18 22:09 
в ответ anly 04.09.18 20:01
Даже Майкрософт в интерфейсах работы с файлами предоставляет асинхронные методы

Страное высказывание. Асинхронные методы предоставляются там где надо и возни с ними получается прилично.

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

Судя по описанному концепту, возится вам с проектом долго и нудно. Никогда бы так не делал.

Один раз попробовал сделать "асинхронную стате машину", через какое то время заработала, но работа зависела от дуновения ветра. В итоге плюнул и оставил один единственный треад в котором все и крутилось. Блин, земля и небо.


Сейчас для больших проектов использую следующий концепт: есть набор изолированных модулей выполняющих связанную группу задач. Модули взаимодействуют через асинхронные сообщения, для логики состояний асинхронная модель преобразуется в синхронную.

Все модули построены по одинаковому принципу, сложная иерархия классов практически не нужна. И интерфейсы и потоки используются только тогда когда действительно требуется.

#2 
anly коренной житель04.09.18 23:35
anly
NEW 04.09.18 23:35 
в ответ AlexNek 04.09.18 22:09, Последний раз изменено 04.09.18 23:42 (anly)

вот был например такой интерфейс:

interface IExample

{

void Fun1();

bool Fun2();

}

после преределки получаем такое:

interface IExample

{

Task Fun1Async();

Task(bool) Fun2Async(); -- треугольные скобки вокруг bool

}

static class IExampleEx

{

public static void Fun1(this IExample p) { p.Fun1Async().Wait(); }

public static bool Fun2(this IExample p) { return p.Fun2Async().Result; }

}


И такое решение позволяет не менять код, который уже использует IExample, что в принципе - изящно.

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


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


Мое замечание, что избежать блокировки юзер-интерфейса можно вообще без переделки всех выше упомянутых СОТЕН интефейсов, а создав Task по конкретному, проблемному юзер-событию, шефы не восприняли.

Я им ради смеха, дабы дурь этой затеи стала виднее, предложил, чтоб сделать "еще лучше", не только все функции интерфейсов сделать асинхронными, а вообще ВСЕ функции, ВСЕХ классов сделать таковыми, включая например оператор [] какой либо коллекции. Но с юмором у немцев туго: они вообще не поняли аналогии моего предложения с ихним.улыб

Проклят нарушающий межи ближнего своего (Втор.27:17)
#3 
AlexNek патриот04.09.18 23:46
AlexNek
NEW 04.09.18 23:46 
в ответ anly 04.09.18 23:35
чтобы ни дай бог не заблокировать надолго юзерский-интерфейс

Винформс что ли?

Срочно ищите другую работу при таком подходе ничего хорошего не придвидится.

#4 
AlexNek патриот05.09.18 00:01
AlexNek
NEW 05.09.18 00:01 
в ответ AlexNek 04.09.18 23:46
Но с юмором у немцев туго

Так это еще и Задорнов фиг знает когда рассказывал.

Типа на итальянской границе спрашивают - наркотики есть? Ответ - ой, извините дома забыл. Погранцы ответили, что то типа в следующий раз не забудьте, а то мы план не выполняем.

На германской тут же спросили домашний адрес. спок

#5 
anly коренной житель05.09.18 00:15
anly
NEW 05.09.18 00:15 
в ответ AlexNek 04.09.18 23:46
Винформс что ли?
да вроде WPF.
Срочно ищите другую работу при таком подходе ничего хорошего не придвидится.
Да это меня туда подключили, т.к. я своему непосредственному шефу (с которым я другие программы поддерживаю) стал канючить что скушновато стало - мало лаж, мало новых фич. Вот он для меня задачку и выклянчил. Но есть надежда, что опомнятся таки упомянутые руководители, т.к. делал все это я в отдельной-экспериментальной ветке, и может она так и сгинет не слившись с основным стволом.
Проклят нарушающий межи ближнего своего (Втор.27:17)
#6 
AlexNek патриот05.09.18 00:33
AlexNek
NEW 05.09.18 00:33 
в ответ anly 05.09.18 00:15
да вроде WPF.

ну это надо умудрится, так фигово написать. Ни разу еще не было под WPF


Но есть надежда, что опомнятся таки упомянутые руководители

не а, у меня никакой надежды. Только когда отладка начнется и локализация. Должны появлятся "случайные" вылеты "конфликта потоков"

#7 
Программист коренной житель05.09.18 09:04
NEW 05.09.18 09:04 
в ответ anly 04.09.18 20:01
А делается это созданием каждому интерфейсу еще одного статического класса который имплементирует для каждой функции extensios (ну там где this интерфейса первый аргумент), а имплементация вызывает интрерфейсную функцию (уже возвращающую Task) и тут же Wait() или Result.
[...]
А пока получается, что каждый вызов любой функции интерфейса создает Task, и тут же ждет ее завершение. Т.е. по сути работает как и раньше - синхронно.

Мне кажется, что это выстрел себе в ногу :) И потом ты будешь долго и упорно выискивать баги.

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

#8 
Murr патриот05.09.18 10:08
Murr
NEW 05.09.18 10:08 
в ответ anly 04.09.18 20:01

Вот этого я и не догоняю - нафига?!

------

Для ответа, вообще-то, надо знать и понимать саму задачу.

У меня вот висит одна несложная часть - на серваке запускается процесс и генерит файлы.

Файлов - много. Процесс - длительный.

По окончании надо перекачать нужное из сгенеренного на клиента.

Пока написано примитивно - запуск и поолинг. Работает, НО! Не нравится.

А мне бы два асинхронных нотификатора - по каждому файлику и по процессу в общем - было бы много по-проще.

Но пока - не могу.

А так - да, буду переводить на асинхронику...

#9 
Murr патриот05.09.18 10:11
Murr
NEW 05.09.18 10:11 
в ответ AlexNek 04.09.18 22:09

В итоге плюнул и оставил один единственный треад в котором все и крутилось.

------

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


#10 
Murr патриот05.09.18 10:27
Murr
NEW 05.09.18 10:27 
в ответ anly 04.09.18 23:35

шефы не восприняли.

-----

Правильно не восприняли.

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

Сейчас вот надо переделывать кусок проектов - сразу не вынес в отдельные либы - было непонятно что и как, а сейчас - надо переделывать И чистить старый код.

Много пустой работы. Сейчас - много, но потом - окупится.


сделать "еще лучше"

------

Прямо вчера чинил хорошее.

В функции - свитч на десяток позиций и... формула для того что не попало в свитч.

Сначала думал, что свитч надо загнать в словарик, а по отсутствию - считать.

Но вот ночью в голову стукнуло - а зачем Я это буду делать так сложно и так медленно работающее?

Там ведь все что надо - массив на 40 элементов (знание предметки!) и просчитать его ОДИН раз.

Дальше - чисто индексирование.

Заодно - следующая операция - деление на значение полученного элемента - почему бы ее не

заменить умножением, поделив при инициализации массивa единицу на коэффициент?

Пустяки? Да! Но там это будет считаться по 50 тыс раз на цикл - есть смысл сделать правильно.

#11 
Murr патриот05.09.18 10:29
Murr
NEW 05.09.18 10:29 
в ответ AlexNek 05.09.18 00:01

На германской тут же спросили домашний адрес.

-----

Угу... В таком варианте нужно иметь недвижимость на луне и предъявлять сертификат на право владения. смущ

#12 
Murr патриот05.09.18 10:32
Murr
NEW 05.09.18 10:32 
в ответ Программист 05.09.18 09:04

Очевидно, что работать все будет только до тех пор, пока все эти переделки работают синхронно.

-----

Да и ради бога - челу было скучно и он поразвлекался чуток в поиске/замене.

А что работает не так как планировалось - это к тем кто планировал.

#13 
anly коренной житель05.09.18 17:41
anly
NEW 05.09.18 17:41 
в ответ Программист 05.09.18 09:04, Последний раз изменено 05.09.18 17:48 (anly)
вое же решение не делает программу асинхронной. Только видимость.
ну да. Именно такая задача передо мной и была поставлена. Это нужно, по словам руководства, чтобы в будущем кому-то (уже не мне) было легче огранизовать асинхронность, если приспичит.


Я сам никакой пользы от моей работы не вижу, а только убытки:

- при многопоточности труднее чего нибудь отлаживать

- старт/завершение/ожидание потока - требует дополнительной производительности

- требования руководства (если приспичит) легко решаются без моей этой работы.


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

Проклят нарушающий межи ближнего своего (Втор.27:17)
#14 
AlexNek патриот05.09.18 20:15
AlexNek
NEW 05.09.18 20:15 
в ответ anly 05.09.18 17:41
Т.е. ни одного плюса я не узрел.

не только Вы смущ

#15 
Программист коренной житель06.09.18 08:55
NEW 06.09.18 08:55 
в ответ anly 05.09.18 17:41

Я сам никакой пользы от моей работы не вижу, а только убытки:

- при многопоточности труднее чего нибудь отлаживать

Смотря что ты понимаешь под "трудностью отлаживать". Логику потока отлаживать в многопоточной среде не сильно труднее, чем в однопоточной.

А вот синхронизацию потоков и взаимодействие между потоками - это да, тут все сложно. Впрочем, твое решение ломает как раз синхронизацию и именно с этим придется возиться тому, кто будет разгребать твое "решение".


- старт/завершение/ожидание потока - требует дополнительной производительности

Ничего драматичного.


- требования руководства (если приспичит) легко решаются без моей этой работы.

:) ну твоя работа не делает приложение многопоточным. Это уже выяснили :) Более того, твое решение только портит работающий код (пусть и с блокировкой UI). Мне кажется, что тут в разговоре с начальством нужно упирать на то, что если уж делать программу многопоточной, то делать надо сразу правильно, а это будет очень долго и дорого.

#16 
anly коренной житель06.09.18 18:22
anly
NEW 06.09.18 18:22 
в ответ Программист 06.09.18 08:55, Последний раз изменено 06.09.18 18:41 (anly)
понимаешь под "трудностью отлаживать". Логику потока отлаживать в многопоточной среде не сильно труднее, чем в однопоточной.
понимаю что написал: многопоточность. А не дебагить в одном потоке.
Ничего драматичного.
ну в приведенном случае как раз драмматично. Ибо наверняка какой либо интерфейс дергается где нибудь в цикле, при этом каждый раз создается/ждется/убивается поток.
Более того, твое решение только портит работающий код (пусть и с блокировкой UI).
дык об этом с самого начала и речь! Причем решение не моё, мне сразу подсказали как делать.
Мне кажется, что тут в разговоре с начальством нужно упирать на то, что если уж делать программу многопоточной, то делать надо сразу правильно.
так об этом я на митинге и говорил, на что один из начальников сказал, что не для этого меня временно привлекли к проекту, а если я этим займусь, то мне хватит работы до пенсии.

И я совершенно согласен - хватит, если конечно делать то что они говорят.

А если решать только проблемные места, на чем я настаивал, то это - дни, максимум - недели.


там еще была идея (слава те господи отменили!) не только функции интерфейсов делать асинхронными, но и все проперти - сперва переделать в функции, ну а потом понятно: раз это функции, значит асинхронны.


Ну представьте себе, что например все функции класса string возвращают Task. Вот на подобии такого я и сделал.

Пункт уже закрыт, начальство довольно. Я уже другими делами занят.

Но совесть моя спокойна: если вся эта хрень что пока в отдельной ветке, всё же вольется в транк, - люди знают я был против.

Проклят нарушающий межи ближнего своего (Втор.27:17)
#17 
AlexNek патриот06.09.18 20:09
AlexNek
NEW 06.09.18 20:09 
в ответ anly 06.09.18 18:22
Но совесть моя спокойна: если вся эта хрень что пока в отдельной ветке, всё же вольется в транк, - люди знают я был против.

А не переживайте, по другому здесь низзя.

Я уже давно нигде ни на чем не настаиваю. Сказал, и жду. Через какое то время сами прибегут. спок Хотя бывает, что и "дурное решение" работает. Клиенту то на внутренности плевать, главное чтобы работало.

Решение то для ПМ очень вкусное, просто тонна автоматической работы, а проект "остается такой какой был". Ну а другому, поручим найти эту долбанную задержку и все - проблема решена.

Что можно еще попробовать сделать - найти того Гуру, который это придумал и поговорить с ним о проблемах. Только если команда новая, будет сложновато, нужно хоть немного знать человека, как с ним разговаривать. Во всяком случае, не говорить, что решение полное Г. А типа, вот я вижу проблемы 1,2,3 как вы планировали их решить?

Сделайте небольшой тест проект. Вначале как было, потом только с требуемыми изменениями, а после чтобы работало как надо. Хотя может в небольшом тесте ничего и не будет видно.


#18