Comments 115
После первого же примера кода расхотелось читать дальше:
private static ITelegramBotClient _botClient;
private static ReceiverOptions _receiverOptions;
А зачем это поля, а не переменные? Почему они статические?
using var cts = new CancellationTokenSource();
Зачем создавать CancellationTokenSource
, если вы его никогда не активируете?
await Task.Delay(-1);
...а выходить из программы не надо?
После первого же примера кода расхотелось читать дальше
Мне кажется проблема Хабра в том, что те кто знают и умеют хорошо - ничего не пишут. А те кто знают и умеют, но допускают ошибки - пишут и получают шишки.
На Хабре про Телеграм бота на C# тут, тут и тут. Считаю что - больше статей Богу статей, прошлые три мне не помогли.
Нет никакой проблемы. Подобных статей написано на разных ресурсах, включая хабр, огромное количество и все они под копирку. Но помимо хабра и статей, если другие источники, в которых можно посмотреть как и что делается и как делают другие люди.
Тем более у dotnet хорошее комьюнити у которого всегда можно поспрашивать вопросы и попросить примеры.
ИМХО более управляемо и понятнее стартовать бота подобным образом:
https://github.com/ImoutoChan/GreenCaptchaBot
https://github.com/ForNeVeR/Megadeth
И в дальнейшем будет более проще им управлять (например, прикрутить админку или сорт оф)
А те кто знают и умеют, но допускают ошибки - пишут и получают шишки.
Так это же хорошо. Смысл "шишек" в том, чтобы люди, которые допускают ошибки, исправлялись, а те, которые читают - видели, что это ошибки, и так делать не надо.
Приветствую. Спасибо за критику, ваши замечания действительно верны, просто изначально я хотел написать кучу методов и классов, а потом передумал, так как посчитал это неуместным для первой статьи, вот и забыл некоторые моменты подправить. Еще раз спасибо за критику, во второй статье (она будет продолжением этой) я поправлю код.
...а выходить из программы не надо?
Ctrl+C или простое закрытие консоли уже не работает ?
Зачем создавать
CancellationTokenSource
, если вы его никогда не активируете?
Он используется в старте бота, в обработчике апдейтов и ошибок, а также его можно использовать, чтобы остановить бота, например, поставить while(!cts.Token.IsCancellationRequested)
Он используется в старте бота, в обработчике апдейтов и ошибок
Нет, не используется. Все, что вы делаете - это передаете токен (не source) в StartReceiving
. Но поскольку вы никогда не активируете сам CancellationTokenSource
, это совершенно бесполезно, и можно с тем же успехом передать CancellationToken.None
.
также его можно использовать, чтобы остановить бота, например, поставить while(!cts.Token.IsCancellationRequested)
Где и зачем?
Вместо await Task.Delay(-1);
ставим этот цикл и по какой-нибудь команде используем cts.Cancel
. Про сам source я понял, спасибо.
Вместо await Task.Delay(-1); ставим этот цикл
Кажется, вы не особо работали с cooperative cancellation.
var task = _botClient.ReceiveAsync(UpdateHandler, ErrorHandler, _receiverOptions, cts.Token);
// [...]
await task;
По крайней мере, вы так не будете бесполезно тратить ресурсы в заблокированном потоке.
по какой-нибудь команде используем cts.Cancel .
По какой? Где?
Кажется, вы не особо работали с cooperative cancellation.
Верно, я вообще по сути новичок, и учусь на всяких бесплатных ресурсах.
По крайней мере, вы так не будете бесполезно тратить ресурсы в заблокированном потоке.
Ну так здесь бот запуститься и тут же выключится. Мы же используем поллинг, а значит нам нужно создать бесконечный цикл, иначе бот не будет получать сообщения. Можно, конечно, переписать на вебхуках, но я, к сожалению, так не умею.
По какой? Где?
Можно сделать консольные команды. Можно сделать админ-меню (админ-команду) в самом боте.
Верно, я вообще по сути новичок, и учусь на всяких бесплатных ресурсах.
Может быть тогда не стоит использовать в статьях, где вы учите других, то, что вы еще не знаете?
Ну так здесь бот запуститься и тут же выключится.
С чего бы?
Мы же используем поллинг, а значит нам нужно создать бесконечный цикл
Нам ничего не нужно. За цикл поллинга отвечает библиотека, которую вы используете.
Можно, конечно, переписать на вебхуках, но я, к сожалению, так не умею.
Так на вебхуках ничего не изменится ровным счетом (с этой точки зрения).
Можно сделать консольные команды. Можно сделать админ-меню (админ-команду) в самом боте.
Слушайте. Типовое решение такого "админ-меню" - это
Console.WriteLine("Press Enter to exit...);
Console.ReadLine();
cts.Cancel();
Пойнт в том, что это ставится вместо вашего бесконечного цикла или await
. Угадайте, почему.
Может быть тогда не стоит использовать в статьях, где вы учите других, то, что вы еще не знаете?
Как пользоваться токеном я в курсе, и для правильной (да, его можно не указывать, но так лучше не делать, иначе могут быть проблемы при следующих запусках бота) работы метода StartReceiving
он необходим.
Нам ничего не нужно. За цикл поллинга отвечает библиотека, которую вы используете.
Она не блокирует основной поток, если не ставить никакие блокирующие циклы, то код запуститься и тут же завершится. А вот эта часть кода:
var task = _botClient.ReceiveAsync(UpdateHandler, ErrorHandler, _receiverOptions, cts.Token);
// [...]
await task;
вообще работать не будет, так как методStartReceiving
(в вашем случае ReceiveAsync, и это важно, дальше поймете почему, я не просто придираюсь) имеет тип void
, и как нам тогда ожидать завершения этого метода ?
Слушайте. Типовое решение такого "админ-меню" - это
В чем проблема написать свой хендлер с консольными командами или тупо взять мой код и заменить мое бесконечное ожидание, на вот это ?
В этой статье я учу писать ботов . Я рассказываю про то, какие бывают типы приходящих обновлений, какие есть методы и как с ними работать. Если же видите замечания по коду, что он написан неверно, лучше бы рассказали, что конкретно не так и помогли улучшить, нежели тупо строить из себя самого умного и тупо критиковать.
да, его [токен] можно не указывать, но так лучше не делать, иначе могут быть проблемы при следующих запусках бота
Это как так? Что за проблемы? Каким образом передача токена, который вы никогда не активируете (т.е. полностью эквивалентного CancellationToken.None
), избавляет от этих проблем?
Она не блокирует основной поток [... ] методStartReceiving (в вашем случае ReceiveAsync, и это важно, дальше поймете почему, я не просто придираюсь) имеет тип void
Метод ReceiveAsync
имеет тип Task
, и в его описании прямым текстом написано "This method will block if awaited.`
и как нам тогда ожидать завершения этого метода ?
await task;
В чем проблема написать свой хендлер с консольными командами или тупо взять мой код и заменить мое бесконечное ожидание, на вот это ?
В том, что человек, читающий вашу статью, не знает, что это надо сделать и как это делать.
В этой статье я учу писать ботов . Я рассказываю про то, какие бывают типы приходящих обновлений, какие есть методы и как с ними работать.
Если быть точным, вы рассказываете, как пользоваться конкретной библиотекой.
Если же видите замечания по коду, что он написан неверно, лучше бы рассказали, что конкретно не так
Вот я и рассказываю.
Метод ReceiveAsync имеет тип Task, и в его описании прямым текстом написано "This method will block if awaited.`
Тут проблема ровно обратная, на самом деле. Вопреки тому, что написано в документации ("Starts receiving Update
s on the ThreadPool
, invoking HandleUpdateAsync
for each."), в реальности оно запускается в том же треде. Так что разделение на присвоение и await
имеет мало смысла (там нет yield потока), первый вызов заблокирует неизвестно насколько (и, например, не будет показано сообщение "я запущен").
Ctrl+C или простое закрытие консоли уже не работает ?
Конечно, нет. Это аварийное закрытие программы, а надо обрабатывать еще и нормальное.
А как ? Я всегда использую ctrl + c :D
А как ?
...что конкретно?
Я всегда использую ctrl + c
И когда ваш бот крутится на сервере, там он тоже закрывается по Ctrl-C?..
Это намекает нам на то, что вам не очень важен graceful shutdown.
...что конкретно?
Ну вы говорите, что я делаю неправильно, я спрашиваю: как сделать правильно ?
И когда ваш бот крутится на сервере, там он тоже закрывается по Ctrl-C?..
Да, а про graceful shutdown я вообще впервые слышу, как бы печально это не было.
Ну вы говорите, что я делаю неправильно, я спрашиваю: как сделать правильно ?
А это напрямую зависит от того, как вы хотите запускать (и хостить) свой бот.
Да
То есть ваши боты на сервере в продакшне крутятся как интерактивное консольное приложение? Серьезно?
А это напрямую зависит от того, как вы хотите запускать (и хостить) свой бот.
Домашний сервак на убунте, в отдельном скрине как обычное консольное приложение крутится там и все, заливаю туда напрямую из IDE Rider, до этого через SMB.
То есть ваши боты на сервере в продакшне крутятся как интерактивное консольное приложение? Серьезно?
Да, серьезно. Я только начинаю свой путь и делаю, как знаю. Как я увидел в интернете: в других статьях, форумах и других ресурсах - так и делаю. К сожалению, больше мне не откуда брать знания, которые были бы проверены всякими профессорами и прочими умными людьми.
Домашний сервак на убунте, в отдельном скрине как обычное консольное приложение крутится там и все, заливаю туда напрямую из IDE Rider, до этого через SMB.
Так в продакшне делать не надо никогда.
Как я увидел в интернете: в других статьях, форумах и других ресурсах - так и делаю. К сожалению, больше мне не откуда брать знания, которые были бы проверены всякими профессорами и прочими умными людьми.
Официальная документация MS - нет? Откуда, вы думаете, у меня информация берется?
Собственно, это ответ на ваш вопрос "В чем проблема написать свой хендлер с консольными командами или тупо взять мой код и заменить мое бесконечное ожидание, на вот это ?" - в том, что люди будут учиться по вашей статье. А потом говорить "как увидел, так и делаю".
вы наверное с марса? лет 25 как всегда код завершают через ctrl+c и программа просто его обрабатывает, если требуется. Ну изредка есть код где явно написано "Press ESC to Exit.", таких программ наверное две или три?
вы наверное с марса?
Нет, я с бэкенда.
лет 25 как всегда код завершают через ctrl+c
Вот вам всего несколько примеров, когда код завершается не через Ctrl-C:
при остановке контейнера, докер шлет главному процессу образа
SIGTERM
при остановке сервиса Windows, SCM шлет сервису команду Stop
при остановке приложения, IIS запускает весьма сложную процедуру, включающую в себя завершение уже начавшихся запросов
когда окружение AWS Lambda собирается положить рантайм лямбды, оно возвращает событие
Shutdown
в ответ на запрос следующего события (а потом шлетSIGKILL
, если они затянули процесс)наконец, банальные
git log
иgit add -i
в качестве нормативного выхода ожидают клавишуq
у вас какие-то серьезные проблемы судя по комментариям. в этой статье нет ни контейнеров ни сервисов ни IIS и много чего другого, это просто приложение для обучения. Я могу написать вам названия 100500 приложений где никто ничего не ожидает кроме ctrl+c, мир не живет по вашим правилам и не нужно придумывать кто-то энциклопедическое чтобы кого-то ткнуть носом. будьте проще.
в этой статье нет ни контейнеров ни сервисов ни IIS и много чего другого
Вы же написали "всегда код завершают".
это просто приложение для обучения
А в приложениях для обучения ставят ReadLine
, чтобы закрывалось детерминировано и с graceful shutdown.
не нужно придумывать кто-то энциклопедическое чтобы кого-то ткнуть носом
Это не энциклопедическое, это приложения, с которыми я повседневно работаю (кроме сервисов Windows, они мне перестали быть нужны лет 5-10 назад). Вот systemd
для меня да, энциклопедическое знание, я под него никогда не интегрировал.
И да, под двумя из перечисленных выше вариантов я еще и поднимал боты для мессенджеров, так что немножко понимаю, о чем речь.
Вы же написали "всегда код завершают"
и там же я еще кое что написал, но вам это неинтересно.
ну и в целом сервис висящий на экране и ждущий ввода от пользователя уже вызывает вопросы. то что сервису можно отправлять команды это понятно, но не так как вы думаете (или пытаетесь тут показать).
И да, под двумя из перечисленных выше вариантов я еще и поднимал боты для мессенджеров, так что немножко понимаю, о чем речь.
Супер. То есть вы, ваш опыт и то с чем работали вы это хорошо, а другого просто не бывает? Я вам озвучил свои кейсы и опыт, как минимум они не хуже ваших, о чем спор-то? Что вы где-то нашли сервис который висит с активным окном и ждёт команду? Ну поздравляю, я такие вообще никогда не видел, всегда ими управлял через стандартные интерфейсы.
ну и в целом сервис висящий на экране и ждущий ввода от пользователя уже вызывает вопросы
У меня он тоже вызывает вопросы. А вот у автора поста - нет.
То есть вы, ваш опыт и то с чем работали вы это хорошо, а другого просто не бывает?
Почему же? Другое вполне себе бывает. Но в случае с .NET я, мне кажется, видел все основные способы развертывания сервисов.
Я вам озвучил свои кейсы и опыт
А вот кстати нет, не озвучили вы свои "кейсы" (ну или я их пропустил/забыл в этой большой дискуссии, что возможно, к сожалению). То, что я знаю про вас - это то, что
вы "не пересекаетесь" с продакшн-кодом
вы пишете на 4.8 и (Windows?) Forms в 99% случаев
о чем спор-то?
О том, как корректно обрабатывать завершение сервисов в .NET.
Что вы где-то нашли сервис который висит с активным окном и ждёт команду?
Вообще, я не знаю, откуда вы это взяли. Я такого не говорил.
У меня он тоже вызывает вопросы. А вот у автора поста - нет.
В общем как я понял вы к академической среде не имеете никакого отношения, вы в этом профессиональный теоретик. Предлагаю им и оставаться, как учитель вы никогда не состоитесь.
А вот кстати нет
Обучение написанию бота на C# или в эту статью еще зачем-то можно приходить?
О том, как корректно обрабатывать завершение сервисов в .NET.
Это вам нужно читать статью - управление сервисами в .NET
Вообще, я не знаю, откуда вы это взяли. Я такого не говорил.
Это вытекает из беседы. Когда висит окно с запущенной консольной программой и её нужно прервать - жмут на Ctrl+C. Вы же пишете о том, что этого делать не нужно, то есть вы в своих кейсах где-то находите окна сервисов (именно вы заговорили про сервисы, хотя это отдельный класс приложений Windows), а потом завершаете их работу любым другим способом кроме Ctrl+C (как я понимаю до этого нужно еще и обработчик соответствующий написать). То есть понятно когда написан реальный сервис, который поднимается в фоновом режиме, не показывает никаких окон и обрабатывает необходимые команды. А ваш кейс абсолютно непонятен. Из всех таких программ я могу вспомнить только майнеры, но они не являются сервисами и корректно обрабатывают завершение по Ctrl+C. Из тех программ что я активно использую это ffmpeg/convert/image - они всегда прерываются по Ctrl+C.
Вы в своем поведении похожи на человека который зашел с класс трудовика в средней школе и стал детям, которые лупят молотком по жестянке, объяснять про ЧПУ. Это всё здорово, но неуместно. Особенно в той манере, какую выбрали вы. Уместным было бы (как я), написать автору в личные сообщения с пожеланием обратить моменты в будущих статьях на те или другие вопросы, возможно, в ходе диалога с автором подсказать какое-то направление. Но вам это не нужно, у вас ровно два пунктика в этом разговоре - ЧСВ и боль перфекциониста. Но это не конструктивно.
В общем как я понял вы к академической среде не имеете никакого отношения
...интересно, из чего вы сделали такой (ошибочный, кстати) вывод?
Предлагаю им и оставаться, как учитель вы никогда не состоитесь.
Некоторое количество успешно отучившихся у меня курсов с вами не согласятся.
Обучение написанию бота на C#
Хм, я не знал, что вы это считаете кейсом. Ну ладно, окей.
Это вам нужно читать статью - управление сервисами в .NET
Зачем мне ее читать? Я-то это знаю в достаточной мере.
Когда висит окно с запущенной консольной программой и её нужно прервать - жмут на Ctrl+C.
Прервать - да. Остановить - не обязательно. Примеры выше. Но дело, однако, в том, что бот должен запускаться не как консольная программа, а как сервис.
Вы же пишете о том, что этого делать не нужно
Ну да, консольная программа должна предоставлять другие способы выхода.
именно вы заговорили про сервисы, хотя это отдельный класс приложений Windows
Сервисы, демоны - все, что крутится в фоне, не важно, в Windows или в Linux. (обратите внимание, что автор статьи пишет под линукс).
то есть вы в своих кейсах где-то находите окна сервисов [...], а потом завершаете их работу любым другим способом кроме Ctrl+C
Нет, ничего такого я не делаю. Зачем?
То есть понятно когда написан реальный сервис, который поднимается в фоновом режиме, не показывает никаких окон и обрабатывает необходимые команды.
Вот приблизительно так и должен быть запущен бот.
А ваш кейс абсолютно непонятен.
Какой конкретно мой кейс? Я пока вижу только что-то, что вы себе придумали.
Мой типовой "кейс" - это стандартное веб-приложение, запущенное стандартным же для хоста способом. Если я могу положить его в контейнер - вообще прекрасно.
Но вам это не нужно
Я, в общем-то, прямым текстом озвучил свои задачи: меня в первую очередь интересует не обучение автора, а то, чтобы читатели статьи видели, каких ошибок не надо совершать. Эта задача личной перепиской не решается.
Но дело, однако, в том, что бот должен запускаться не как консольная программа, а как сервис.
Если чуть более точно - не как интерактивная консольная программа. Так-то что сервисы, что демоны, что ведущие процессы в контейнерах - консольные программы...
Если чуть более точно - не как интерактивная консольная программа. Так-то что сервисы, что демоны, что ведущие процессы в контейнерах - консольные программы...
Да я прекрасно это понимаю, но это совсем не нужно делать в первой статье, которая просто знакомит с шагами и первым стартом бота. Выключите уже в себе перфекциониста.
это совсем не нужно делать в первой статье, которая просто знакомит с шагами и первым стартом бота.
Да, в первой статье достаточно сделать интерактивное консольное приложение, которое закрывается по Console.ReadLine()
, потому что так проще всего продемонстрировать корректное завершение работы приложения.
.интересно, из чего вы сделали такой (ошибочный, кстати) вывод?
просто у вас вместо 1-11 классов был бы только универ да еще для тех у кого опыта вагон и тележка.
Прервать - да. Остановить - не обязательно
Вы не сможете остановить корректно программу не имеющую такого механизма.
Примеры выше
Это сова на глобусе.
бот должен запускаться не как консольная программа, а как сервис.
Аналогия: когда столяр учит вас пользоваться кондуктором для скрепления изделий под 90 градусов, он, внезапно, говорит и показывает кондуктор, а занятие о том, что при скреплении следует пользоваться шкантами будет уже позднее. От малого к большому.
А у вас к обучающему коду требования как к презентации Apple.
Ну да, консольная программа должна предоставлять другие способы выхода.
Должны, да не обязаны, особенно в формате обучалки.
Сервисы, демоны - все, что крутится в фоне, не важно
Важно, так как никто не пишет в этой статье сервис.
Нет, ничего такого я не делаю. Зачем?
Тогда чем вас так не устраивает Ctrl+C в конкретно взятом примере? Напишите свой код с другим вариантом завершения, в статье это вообще не принципиально.
Вот приблизительно так и должен быть запущен бот
Да кто бы спорил. Но так устроен процесс разработки сервисов, что они изначально пишутся как приложения. Возможно именно в Линуксе это не обязательно, но в винде именно так. И придумано это не мной. А тут этот функционал совершенно не к месту.
это стандартное веб-приложение
его нет в этой статье
Если я могу положить его в контейнер - вообще прекрасно.
В какой контейнер? 3 или 5 тонн?
каких ошибок не надо совершать
Это не ошибки, а допущения. Почитайте книжки, пример я вам уже приводил.
просто у вас вместо 1-11 классов был бы только универ да еще для тех у кого опыта вагон и тележка.
Ничего не понял. "Только универ" вместо 1-11 классов? А?
Вы не сможете остановить корректно программу не имеющую такого механизма.
Какого механизма?
Аналогия
Ваша аналогия мне не понятна.
А у вас к обучающему коду требования как к презентации Apple.
Нет. Я уже описал свои требования к обучающей статье.
Должны, да не обязаны, особенно в формате обучалки.
Понятное дело, что никто никому ничего не обязан, но я ожидаю от обучающей статьи корректного кода. Вставить Console.ReadLine()
- просто, и позволило бы решить все проблемы хором.
Тогда чем вас так не устраивает Ctrl+C в конкретно взятом примере?
Тем, что нет гарантии, что бот не потеряет сообщения.
Да кто бы спорил.
Ну вот автор, скажем, не умеет запускать боты иначе, чем интерактивные консольные приложения.
Возможно именно в Линуксе это не обязательно, но в винде именно так.
...автор, кстати, пишет для линукса.
Это не ошибки, а допущения.
Допущения - это когда автор обучающего материала знает, как надо, но сознательно упрощает для целей урока. А автор статьи, по его собственному признанию, не знает, что такое graceful shutdown, и как же должно быть сделано.
Ну а вещи типа никогда не активируемого CancellationTokenSource
- это просто ошибки, без оговорок на какие либо допущения.
Почитайте книжки, пример я вам уже приводил.
Пример книжки? Хм... Что-то я не нашел этого в ваших сообщениях.
Тем, что нет гарантии, что бот не потеряет сообщения.
Тривиальный демонстрационный пример:
try
{
Console.WriteLine("Started");
while (true)
{
Thread.Sleep(1000);
Console.Write(".");
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
Console.WriteLine("Exited");
}
После нажатия Ctrl-C не выводится Exited
(что логично), что свидетельствует, что программа не может корректно завершить операции.
Сравните поведение с кодом ниже при нажатии Enter (собственно, можно после этого сравнивать поведение при Enter и при Ctrl-C)
try
{
using var cts = new CancellationTokenSource();
Console.WriteLine("Started");
var task = Task.Run(() =>
{
while (!cts.IsCancellationRequested)
{
Thread.Sleep(1000);
Console.Write(".");
}
Console.WriteLine();
Console.WriteLine("Task finished");
});
Console.WriteLine("Press Enter to exit...");
Console.ReadLine();
cts.Cancel();
await task;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
Console.WriteLine("Exited");
}
После нажатия Ctrl-C не выводится
Exited
Пофигу.
А, так вам пофигу на потерю данных в боте. Тогда понятно.
Мне, очевидно, не пофигу.
Да блин, да не бот это, это обучалка пример как его писать и какие основные моменты и конструкции нам нужны, а как там причесать код и сделать завершение работы ДЕЛАЙТЕ САМИ, нафига в статье это вообще показывать?
Да блин, да не бот это, это обучалка
Обучалка должна либо не позволять потерю данных (что на наивном уровне несложно), либо явно оговаривать "вот тут будет потеря данных, про нее мы расскажем потом".
как там причесать код и сделать завершение работы ДЕЛАЙТЕ САМИ
Так откуда читатель статьи узнает, (а) что это вообще надо сделать, и (б) как это сделать?
нафига в статье это вообще показывать?
А "нафига вообще" писать статью "как пользоваться библиотекой X", если у библиотеки X есть (очень неплохая, кстати, лучше, чем у многих) документация?
(замечу, что в этой документации есть пример, аналогичный тому, который статье автора, и в нем нет этой ошибки, а указано решение приблизительно аналогичное моему)
А "нафига вообще" писать статью "как пользоваться библиотекой X", если у библиотеки X есть (очень неплохая, кстати, лучше, чем у многих) документация?
Ну, например, я не задумывался о написании своего бота. Прочитал статью и узнал, что это довольно легко. Также, просто читая код примеров, у меня появились идеи как можно использовать ботов для моих нужд.
При этом, в этой статье минимальное количество менее интересных для меня моментов про корректное завершение процесса, логгирование и другие, безусловно важных, но в данном контексте совершенно лишних телодвижений. Вас почему-то не возмутило наличие кучи switch/case кострукций…
Предполагается, что целевая аудитория этой статьи - люди с минимальным представлением о программировании, и смогут разобраться с архитектурой их собственного проекта уж как-нибудь сами.
Вас почему-то не возмутило наличие кучи switch/case кострукций…
Возмутило; просто я с самого начала сказал, что после первого примера кода смотреть на последующие даже не вижу смысла.
А потом и про свитчи тоже написали, так что повторяться уже нет смысла.
PS
Прочитал статью и узнал, что это довольно легко.
Самое забавное то, что я не считаю, что написать бота - легко. Написать хорошего бота сложно, просто эта сложность лежит не в протоколе обмена, для которого почти всегда можно найти библиотеку, а в поддержании состояния. Но об этом в статье ни слова, афаик.
Ничего не понял
Не сомневался ни секунды.
Какого механизма?
Корректного.
Ваша аналогия мне не понятна
Ничем не могу помочь. Это как с ООП, вы либо можете в него либо нет.
Нет. Я уже описал свои требования к обучающей статье.
Да. Это и есть - пристанище перфекциониста.
Покуда вы не рубите в аналогии, то вот вам еще одна. Это даже не аналогия, а пример из жизни. При обучении разработке на 6502 пишется код, в котором в качестве паузы используется цикл. Занятий через 3-4 этот цикл заменяется на другую конструкцию, работающую через прерывание. То есть в контексте каждого урока вы не уходите за рамки и акцент делается только на какой-то конкретной теме, сам же код может быть разной степени идиотности. Если кому-то чужда такая практика в обучении, ну селяви.
Вставить
Console.ReadLine()
- просто, и позволило бы решить все проблемы хором.
Абсолютно пофигу, нажму Ctrl-C и всё норм.
Тем, что нет гарантии, что бот не потеряет сообщения
А стоит такая задача? Я вижу только статью показывающую общие принципы связанные с запуском бота, а не гайд по идеальному программированию.
Ну вот автор, скажем, не умеет запускать боты иначе, чем интерактивные консольные приложения.
А я скажу больше - мне нужен бот в виде консольного интерактивного приложения, терпеть не могу сервисы. Особенно ненаписанные.
автор, кстати, пишет для линукса
Да по барабану.
Допущения - это когда автор обучающего материала знает, как надо
Это игра в слова не меняющая сути.
Ну а вещи типа никогда не активируемого
CancellationTokenSource
- это просто ошибки, без оговорок на какие либо допущения.
Исправит, не вижу проблемы. Автор вполне адекватен.
Пример книжки? Хм... Что-то я не нашел этого в ваших сообщениях
Пример примера.
Корректного.
Корректного механизма, делающего что?
Абсолютно пофигу, нажму Ctrl-C и всё норм.
Так мы и выяснили, что для вас потеря данных - норм.
А стоит такая задача?
В общем случае - да.
мне нужен бот в виде консольного интерактивного приложения
Тогда напишите его таким образом, это, прямо скажем, несложно. Переход от одного к другому - дело более-менее одной строчки в конфигурации хоста.
Это игра в слова не меняющая сути.
Да нет, это как раз принципиальное отличие допущения от ошибки. Иначе можно сказать, что ваша оговорка "Это не ошибки, а допущения." - это "игра в слова, не меняющая сути".
Исправит, не вижу проблемы.
До сих пор не исправил.
Мне кажется было бы нагляднее если бы код раскидали по методам хотя бы. Вся логика в одном методе это такое себе.
а мне ООП тем и не нравится что раскидывается по одной строчке по миллиону методов и вообще непонятно что и зачем. И вместо того чтобы созерцать единое целое приходится всё запихивать в голову и структуру держать в голове, отвлекся на другой проект и всё, приходишь - а фиг его знает что там и как устроено.
Похоже вы никогда не видели и не пытались изменить внутренность .Select() размером в 300+ строк.
а мне ООП тем и не нравится что раскидывается по одной строчке по миллиону методов и вообще непонятно что и зачем.
Это не ООП, это плохой код. Вы про структурное программирование не слышали?
Это не ООП, это плохой код. Вы про структурное программирование не слышали?
я как раз и пишу таким способом, а вот вы читать не умеете. я пишу про ООП, а не про код автора (уж не знаю с чего вы решили что я пишу про него), так как комментирующий NCNecros как раз и хотел бы видеть код написанный в стиле ООП.
то что я вижу у автора мне понятно, если раскидать по методам то читабельность ухудшится. Кстати в 90-е, когда я изучал программирование об этом как раз говорилось как явный минус ООП. Так как ООП раскрывается на большом коде, так как происходит структурирование данных но объектам и его методам и вы изучаете код как функцию объекта, а не как совокупность команд. Я слава богу такой код не пишу и не читаю. Как-то хотел на github взять для себя исходник чтения файлов типа QOI - это был просто трындец, переносимость нулевая, невозможно взять код за основу и перенести на другой язык. В общем не люблю я ООП, но понимаю чем он полезен и что без него никак.
я как раз и пишу таким способом,
Каким "таким"?
я пишу про ООП, а не про код автора (уж не знаю с чего вы решили что я пишу про него)
Я тоже не про код автора.
так как комментирующий NCNecros как раз и хотел бы видеть код написанный в стиле ООП.
Цитирую дословно: "было бы нагляднее если бы код раскидали по методам хотя бы". Это не про ООП, это про структурное программирование.
Это не про ООП, это про структурное программирование
Угу. Только при процедурном у вас, внезапно, процедуры. Методы и классы - это признаки ООП.
Ме́тод в объектно-ориентированном программировании — это функция или процедура, принадлежащая[1] какому-то классу или объекту.
Как и процедура в процедурном программировании, метод состоит из некоторого количества операторов для выполнения какого-то действия и имеет набор входных аргументов.
Я, вроде, нигде не упоминал процедурное программирование, я оба раза написал о структурном.
я воспринял ваши слова как то, что вы не понимаете о чем пишете (похоже это так), поэтому предположил что вы путаете структурное и процедурное. но раз вы сами признались что ничего не перепутали, то у меня вопросов еще больше к вам, только обсуждать это не вижу смысла, так как парадигма структурного программирования изжила себя очень давно и сейчас она в измененном виде уже подразумевается во всех языках как основа (разве только где-то, где безусловный переход является частью самого ЯП, например ассемблер). В современных языках безусловные переходы реализуются через разные прерывающие конструкции вроде return, break, continue и т.п. Например на платформе ATARI BASIC это в принципе реализовать невозможно, но это и ЯП конца 70-х.
C# это ЯООП и вы либо раскидываете всё по классам и методам либо валите код в один метод реализуя процедурное программирование. Это фуфуфу и говнокод, но это сделать можно.
Тот код который выложил автор уже написан по принципам структурного программирования (а на C# можно это сделать иначе? да что C#, с середины 80-х уже ЯП реализовывали этот подход как основной, я учился в вузе в 90-е и нам уже давали материал именно в контексте структурного программирования).
Тот код который выложил автор уже написан по принципам структурного программирования
Я вроде бы и не говорил обратного.
Я всего лишь сказал, что "раскидывается по одной строчке по миллиону методов и вообще непонятно что и зачем" - это следствие не ООП, а плохого кода. ООП такого не требует.
А умение корректно декомпоновать задачу на иерархические блоки - это как раз и есть основа структурного программирования. Если этого не уметь, не важно, что является блоком - метод или функция.
это следствие не ООП, а плохого кода
так написано всё ООПэшное, по собственной статистике скажу, что в среднем на одну позицию информации в ООП приходится 5-7 строк кода, в процедурном 1.5
Чем меньше операций осуществляется в методе тем выше вес обязательного кода только для оформления. С этим постоянно идёт борьба, во всяком случае в .NET. Что не влияет никак на читаемость кода (или влияет минимально), это только вопрос скорости разработки и компиляции..
А умение корректно декомпоновать задачу на иерархические блоки - это как раз и есть основа структурного программирования. Если этого не уметь, не важно, что является блоком - метод или функция
Подходы изначально разные, нет тождественности между методом и функцией. Разные принципы работы с памятью, то есть с переменными. Тот же "Hello World!" в ООП из одной строки превращается в 20. При этом класс helloworld уже размещают в другом файле. При вызове сначала создает объект скласса helloworld, а потом вызывают метод который выводит текст на экран. И то, если разработчик не пойдет дальше и не сделать отдельный интерфейс по работе с экраном, который используется классом helloworld. Оно выглядит всегда красиво, блоки-блоки-классы-объекты-методы, а на практике - больше кода Богу кода. Но не стану спорить что сейчас без этого некуда.
Когда работаешь с консолью или канвасом там вообще по 3-4 строки кода может быть чтобы что-то вывести на экран (а порой и несколько разных объектов создать дополнительно). Я обычно пишу функцию отдельную где в качестве параметра принимаю все необходимые настройки, тогда хоть код не замусоривается.
так написано всё ООПэшное
Это утверждение нуждается в формализации и доказательстве.
по собственной статистике скажу, что в среднем на одну позицию информации в ООП приходится 5-7 строк кода, в процедурном 1.5
К сожалению, без формальной методики подсчета это исключительно ваше субъективное мнение.
Подходы изначально разные, нет тождественности между методом и функцией.
Инструменты разные. А подход к иерархической декомпозиции один и тот же - я это говорю, как человек, который писал и в ООП, и в ФП, и в процедурной парадигме.
Можно раскидать по одной строчке по миллиону методов, можно раскидать по одной строчке по миллиону функций, а можно раскидать по одной строчке по миллиону процедур. А можно - во всех трех случаях - этого не делать.
Тот же "Hello World!" в ООП из одной строки превращается в 20. При этом класс helloworld уже размещают в другом файле. При вызове сначала создает объект скласса helloworld, а потом вызывают метод который выводит текст на экран.
Я просто оставлю это здесь:
using System;
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Это вот прямо из шабона приложение. И это я еще не стал брать новый .NET, где есть top-level statements.
Это утверждение нуждается в формализации и доказательстве
Доказывайте, если вам это требуется, вы же свой субъективные суждения не подкрепляете доказательствами.
К сожалению, без формальной методики подсчета это исключительно ваше субъективное мнение
Это 25 лет работы, личная статистика, она субъективна, кто бы спорил, но она такая.
А подход к иерархической декомпозиции один и тот же
Нет. Именно поэтому я никак и не могу начать пользоваться ООП, потому что там совсем всё иначе, нужно пересматривать сам подход к реализации и блок схема приложения в процедурном и ООП варианте может выглядеть одинаково, но реализовываться будет иначе.
Можно раскидать по одной строчке по миллиону методов, можно раскидать по одной строчке по миллиону функций, а можно раскидать по одной строчке по миллиону процедур. А можно - во всех трех случаях - этого не делать
Вы все равно упрётесь в то, что в ООП вы будете делать а в процедурном - нет, в обязательном порядке. Даже банальный доступ к данным и там и там различается.
Я просто оставлю это здесь
На самом деле так
Console.WriteLine("Hello World!");
этого достаточно. Но это не ООП, это просто вводная строка в IDE которая сразу что-то делает, это допущение. Если вы напишете код сразу как то требуется, то будет всё весьма печально. Но и в вашем варианте 11 строк, а не одна, то есть формализация кода увеличивает его на 1100%, не меняя сути, об этом и речь.
я это говорю, как человек, который писал и в ООП, и в ФП, и в процедурной парадигме
ну только вы один писали, остальные наверное только читали. у всех свой опыт и взгляд на вещи, на одни и те же вещи. Посмотрите исходники разных библиотек в Nuget, они все +- одинаковые. Если вам кажется что все вокруг говнокодят - да ради бога, только из-за ваших слов код красивее не станет, он такой какой он есть и он всегда сложнее в чтении, понимании и трансляции в другие системы. В ООП очень много конструкций которые вы никак и никогда не перенесёте в процедурное исполнение, вам придется писать очень много кода, поэтому так никто не делает (дураков не так много как бы вам ни хотелось думать). Поэтому мне ближе и понятнее not safe код Си, чем ООП C#. Банальную точку на экране чтобы поставить нужно такую фигуру изобразить, что программировать всё желание отпадает. А когда для ускорения работы начинаются выкрутасы, тем более, костыль на костыле.
вы же свой субъективные суждения не подкрепляете доказательствами.
Когда мои утверждения субъективны, они и не требуют доказательств. Просто теперь явно видно, что ваше утверждение "так написано всё ООПэшное" - субъективно.
Это 25 лет работы, личная статистика, она субъективна, кто бы спорил, но она такая.
Личная статистика за 25 лет легко может быть предвзятой.
Нет. Именно поэтому я никак и не могу начать пользоваться ООП, потому что там совсем всё иначе, нужно пересматривать сам подход к реализации
Почему вы настойчиво приравниваете декомпозицию к чему-то другому? Теперь вот к реализации.
Ну и в любом случае, то, что вы не можете начать пользоваться ООП, потому что там все иначе, означает только то, что вы не можете для себя найти общих принципов. Это не значит, что их нет.
Вы все равно упрётесь в то, что в ООП вы будете делать а в процедурном - нет, в обязательном порядке.
Нет, не упрусь. Я просто не буду раскидывать код по одной строчке ни в одном, ни в другом случае.
Но это не ООП
Почему вдруг?
Если вы напишете код сразу как то требуется, то будет всё весьма печально.
Я написал код сразу так, как требуется, он полностью выполняет задачу и не противоречит никаким принципам.
то есть формализация кода увеличивает его на 1100%, не меняя сути, об этом и речь.
Ну так никто же не заставляет делать эту "формализацию". Речь ровно о том, что каждый сам для себя выбирает, как писать (особенно если мы говорим о C#, который уже давно мультипарадигменный).
Посмотрите исходники разных библиотек в Nuget, они все +- одинаковые.
О нет, они очень разные. Мне по долгу работы периодически приходится в них не то что смотреть, а иногда и править что-нибудь. Так что они весьма разные.
код красивее не станет, он такой какой он есть и он всегда сложнее в чтении, понимании и трансляции в другие системы.
Возвращаемся к началу коммента, где написано про субъективные суждения, и подставляем: он всегда вам сложнее в чтении, понимании и трансляции. Ну... так бывает, да. Это не значит, что это верно для других людей.
В ООП очень много конструкций которые вы никак и никогда не перенесёте в процедурное исполнение
...зачем бы?
Просто теперь явно видно, что ваше утверждение "так написано всё ООПэшное" - субъективно
а для вас это сразу не понятно и требуется говорить явно?
Личная статистика за 25 лет легко может быть предвзятой
и? вы ссылаетесь на личную статистику, я ссылаюсь, что не так?
что вы не можете для себя найти общих принципов. Это не значит, что их нет.
Я работал с людьми сильно умнее меня в программировании и многие даже пытались меня приучить писать, но не получилось. И вот что странно, они все всегда рассказывали все точно так же как это например написано в книгах. Возможно они тоже не в курсе что есть какие-то "общие принципы". Но в любом случае мы не о принципах говорим, а о коде. И код написанный по ООПэшному всегда выглядит иначе и всегда сильно более запутанный и тяжелый для понимания в силу как раз своих принципов. Писать по ООПэшному так же как и процедурный вариант у вас в принципе не получится, а значит реализацию одной и той же блок-схемы приложения вам неизбежно придется писать по-разному.
Нет, не упрусь. Я просто не буду раскидывать код по одной строчке ни в одном, ни в другом случае.
Будете. Просто для работы с данными у вас уже будет появляться избыточный код - чтение, запись, инициализация, доступность.
Ну так никто же не заставляет делать эту "формализацию"
так простые вещи "в стол" люди так и пишут, в остальном случае пишут так чтобы было "по книжке". Повисите на том же stackoverflow, там эта тема возникает постоянно.
Так что они весьма разные.
"весьма разные" и "+- одинаковые" это одно и то же как "стакан наполовину пуст или наполовину полон", просто вы смотрите на одно а я на другое.
Это не значит, что это верно для других людей.
ну так вы все свои комментарии прогоняйте через этот принцип, может откровение наступит.
зачем бы?
речь не о "зачем", а о том что в ООП код избыточный по конструкции, а в процедурном варианте по реализации
а для вас это сразу не понятно и требуется говорить явно?
Да, для меня это сразу не понятно.
и? вы ссылаетесь на личную статистику, я ссылаюсь, что не так?
И... ничего. Просто полезно это помнить.
Я работал с людьми сильно умнее меня в программировании и многие даже пытались меня приучить писать, но не получилось.
Если не получилось, то не удивительно, что для вас "код написанный по ООПэшному всегда выглядит иначе и всегда сильно более запутанный и тяжелый для понимания в силу как раз своих принципов".
Если вы не научились мыслить в ОО-парадигме, то этот код для вас тяжел в понимании. Как для меня, скажем, код на Хаскеле или еще более формальных языках.
Будете
...нет? Нет, не буду. С чего вы взяли.
Просто для работы с данными у вас уже будет появляться избыточный код - чтение, запись, инициализация, доступность.
Нет, не будет.
Избыточный код у меня появляется, когда я пытаюсь писать на C# в функциональной парадигме, тогда - да. Но с новыми версиями это все легче и легче.
в остальном случае пишут так чтобы было "по книжке".
В реальном продакшн-коде? Далеко не всегда.
речь не о "зачем"
Нет, речь как раз о "зачем". Зачем мне переносить конструкции из ООП в процедурный код?
И... ничего. Просто полезно это помнить
так вы себе где-то записывайте, я это подразумеваю изначально в любом разговоре.
Если не получилось, то не удивительно
А кроме вас тут никто и не удивляется.
Нет, не буду. С чего вы взяли
Тогда вы ничего не напишете в ОО.
Но с новыми версиями это все легче и легче
Это все знают, вопрос в том что вы не хотите писать что, где и когда, вы просто безапелляционно утверждаете. Например я пишу на 4/8 и Forms в 99% случаев и новое меня вообще не касается, при этом я остаюсь в рамках .NET и ООП. На C++ всё еще хуже.
В реальном продакшн-коде?
Без понятия, я с продакшн вообще не пересекаюсь, там вообще всё может быть иначе. А вы когда читаете обучающий код всегда ожидаете увидеть нанотехпологичиный квантовый портал или щепотку говнокода с детскими ошибками?
Зачем мне переносить конструкции из ООП в процедурный код?
Для переноса на платформу где ООП в принципе нет. Для работы с языком в котором нет ООП. В целом для себя, чтобы не задуряться этим ООП. Причины у каждого свои. Еще печальнее что нет переносимости между 4.8 и Core и .NET. Меня тут один фанатик истерично уговаривал с 4.8 перейти на Core 3.1, ну перенёс, год к C# н подходил и всё, тютю. Открыл свой старый проект на 4.8 и пользуюсь дальше.
Тогда вы ничего не напишете в ОО.
Тогда получается, что за последние несколько лет я ничего не написал. Хм. Люди, которые пользуются результатами работы этого "ничего", очень удивятся.
Это все знают, вопрос в том что вы не хотите писать что, где и когда, вы просто безапелляционно утверждаете.
Подождите. Если "все знают", то зачем мне писать, что конкретно и где? Все же и так знают?
А вы когда читаете обучающий код всегда ожидаете увидеть нанотехпологичиный квантовый портал или щепотку говнокода с детскими ошибками?
Когда я читаю обучающий код, я ожидаю увидеть код без ошибок, а если там сделаны упрощения для простоты обучения, то они обозначены (чтобы было очевидно, что так нельзя делать в реальной жизни).
Для переноса на платформу где ООП в принципе нет. Для работы с языком в котором нет ООП.
Зачем мне это? По работе от меня это не требуется.
В целом для себя, чтобы не задуряться этим ООП.
"Для себя" я ФП изучаю, мне это интереснее.
Еще печальнее что нет переносимости между 4.8 и Core и .NET.
Учитывая, что я несколько лет занимаюсь миграцией с 4.8 на более новые версии, мне это забавно слышать. Есть там переносимость, пусть и не один в один. А с Core 3.1 на более новые версии и того проще мигрировать, это я проделывал несколько раз достаточно рутинно.
Зачем мне это?
А речь не про вас.
миграцией с 4.8
речь не о невозможности в принципе одно преобразовать в другое, а о том что для этого нужно будет изучать обе платформы, что мне, например, неинтересно. Вы не сможете просто жмякнуть на проект и он у вас магическим способом превратится в 3.1 и нет тождественности в командах, типа заменить А на Б без изменения основного кода.
Когда я читаю обучающий код, я ожидаю увидеть код без ошибок
Только если его пишет специалист соответствующего уровня. Вы же, являясь таковым (я надеюсь) писать ничего не хотите, значит newbie буду справляться без вас, задевая вашу тонкую душевную организацию.
Тогда получается, что за последние несколько лет я ничего не написал
Нет, вы просто в разговоре зашли в тупик и в такой форме изображаете свой вариант финала, где вы не ударите лицом в грязь.
Подождите. Если "все знают", то зачем мне писать, что конкретно и где? Все же и так знают?
У меня давно копится статистика, что люди умеющие хорошо программировать абсолютно не умеют читать чужие фразы и их понимать, в принципе имеют большие сложности с коммуницированием. Вы очень не первый такой. Ну а теперь расшифрую: "все знают" относится к словам о том, что "с новыми версиями всё легче", и не более того. Приведу аналогию (хотя в аналогии мало кто умеет, но всё же): вы знаете, что на Камазе можно перевезти 4 тонны песка, но это не значит, что вы умеете управлять Камазом.
о том что для этого нужно будет изучать обе платформы, что мне, например, неинтересно
Не, ну если неинтересно, нет задачи - то незачем, да. Это не значит, что нет переносимости, это значит, что вам незачем тратить усилия на перенос. Это тоже нормально.
У нас вот есть понимание, зачем нам это нужно, вот мы и тратим на это ресурсы.
Только если его пишет специалист соответствующего уровня.
А когда обучающий текст пишет не-специалист, получается плохой обучающий текст. Поэтому не-специалистам такие тексты писать не стоит.
Нет, вы просто в разговоре зашли в тупик и в такой форме изображаете свой вариант финала, где вы не ударите лицом в грязь.
...или же ваши представления об ООП - а речь была о нем, а не о моей персоне - несколько дальше от реальности, чем стоило бы для разумного разговора.
У меня давно копится статистика, что люди умеющие хорошо программировать абсолютно не умеют читать чужие фразы и их понимать, в принципе имеют большие сложности с коммуницированием.
У меня давно копится статистика, что люди, говорящие, что другие люди не умеют понимать написанное, не очень хорошо умеют - а иногда просто не хотят - выражаться так, чтобы их поняли.
Ну а теперь расшифрую: "все знают" относится к словам о том, что "с новыми версиями всё легче", и не более того.
"Это понятно". А что же я не хочу, по вашим словам, писать?
Это не значит, что нет переносимости
Речь не о том что совсем невозможно, а то том что задача не тривиальная (и часто очень не тривиальная), я с 3.1 на 4.8 переделывал одну штуку, в итоге плюнул и просто сразу написал на 4.8 с нуля, такая же фигня с питоном 2.7 и 3.
У нас вот есть понимание, зачем нам это нужно, вот мы и тратим на это ресурсы
Вы - не я, что логично.
А когда обучающий текст пишет не-специалист, получается плохой обучающий текст
Для меня в подавляющем большинстве случаев именно такие тексты и являются востребованными. Так как специалисты либо не пишут ничего (кто-то не хочет, а кто-то, как вы, считает что уже всё написано в спеках и мануалах), либо пишут так, что совсем непонятно.
Поэтому не-специалистам такие тексты писать не стоит
Не так. Специалистам не стоит считать что у них есть право на что-то указывать. Не ваше это болото.
или же ваши представления об ООП несколько дальше от реальности, чем стоило бы для разумного разговора
Уже очень давно стало скучно, поэтому сойдёмся на том что вы правы во всём, статью от вас мы же всё равно не увидим, как написать правильного бота на C#. Так что.
что люди, говорящие, что другие люди не умеют понимать написанное, не очень хорошо умеют - а иногда просто не хотят - выражаться так, чтобы их поняли.
Со мной это не сработает, я 25 лет работаю со студентами и они всё понимают прекрасно.
А что же я не хочу, по вашим словам, писать?
Я уже потерялся в переписке, видимо речь о том что вы не делитесь опытом на уровне новичка. Когда специалист уходит в высь, у него появляется профдеформация и он на одни и те же вещи начинает смотреть преломляя их под себя и свои навыки. Поэтому очень не все хорошие специалисты например могут работать с детьми на платных курсах. У нас в универе таких просто единицы. Приглашаем, потом сидим в аудитории слушаем и смотрим на тестовом занятии, а человек просто не может ни объяснить ни научить, нет методического материала, нт плана занятий, самостоятельный занятия не умеют разрабатывать. Хотя сам в регалиях именитый профи. Уверен он на разных площадках тоже может писать и комментировать что-то, но толку от этого ноль.
я с 3.1 на 4.8 переделывал одну штуку
В смысле - с Core 3.1? Ну так это же бэкпорт, он не обязан поддерживаться.
Специалистам не стоит считать что у них есть право на что-то указывать.
Интересно, почему бы у меня не было права указывать на что-то в статье, до тех пор пока я остаюсь в рамках правил ресурса?
(но вообще, конечно, идея, что специалисты не имеют права на что-то указывать в их области специализации - это... занятно)
Со мной это не сработает, я 25 лет работаю со студентами и они всё понимают прекрасно.
А я (хм, сбился со счета) много лет читаю чужую письменную речь и, судя по результатам, прекрасно ее понимаю. Так что тоже не выйдет.
Я уже потерялся в переписке, видимо речь о том что вы не делитесь опытом на уровне новичка.
Даже если предположить, что это так - а что, должен?
(хотя, конечно, в контексте оригинальной фразы предположить такую трактовку я совершенно не мог бы)
У нас в универе таких просто единицы.
Если не секрет, что конкретно вы преподаете? Просто любопытно.
В смысле - с Core 3.1? Ну так это же бэкпорт, он не обязан поддерживаться.
рукалицо, причем здесь это...
Интересно, почему бы у меня не было права указывать на что-то в статье, до тех пор пока я остаюсь в рамках правил ресурса?
Я думаю это будет мой последний ответ вам, вы не следите за разговором и не понимаете контекста. Это не только скучно, но и утомительно, тем более что объяснение чего-либо вам постигнет та же участь.
Даже если предположить, что это так - а что, должен?
Нет, но тогда откуда претензии к тем кто делится?
Если не секрет, что конкретно вы преподаете? Просто любопытно.
Маркетинг на кафедре экономики и Теорию и технологию программирования на кафедре информационных технологий.
рукалицо, причем здесь это...
При том, что вы это зачем-то сюда притащили. Вы, не я.
Нет, но тогда откуда претензии к тем кто делится?
Оттуда, что делиться надо качественной информацией, а не абы какой. Это вопрос из серии "откуда претензии к тем, кто делится гнилой едой", раз вы так любите аналогии.
Маркетинг на кафедре экономики и Теорию и технологию программирования на кафедре информационных технологий.
Спасибо.
Да, я изначально так и писал, но потом передумал, так как проект показался мне простым. В следующей статье (она будет продолжением этой), я уже буду использовать разные классы и методы, например, хендлер (обработчик) inline-клавиатуры, хендлер сообщений и т.д.
Спасибо, для начала все понятно
Меня больше в таких программах интересует параллельное выполнение, и многопоточность (ведь как я понял тут "закидываются" в твой код на колбэки, не дожидаясь ответов?!)
Являются ли все созданные объекты от этой библиотеки потокобезопасными?
в отличии от придирчивости @lair
не совсем понял что именно вы хотите распараллелить? система работает по принципу "вопрос-ответ".
Например, что будет если в момент отправки одного ответа придет следующий "вопрос"?
это вопрос к Дурову, я не знаю как именно сервер ТГ обрабатывает запросы. И главное - как вы своим кодом можете на это влиять.
это вопрос к Дурову, я не знаю как именно сервер ТГ обрабатывает запросы.
Сервер ТГ тут не при чем - он, очевидно, имеет достаточную степень паралеллизма, особенно учитывая, что их заведомо больше одного.
И главное - как вы своим кодом можете на это влиять.
Это тоже весьма понятно: если мой бот блокирует получение новых сообщений от сервера на время обработки уже полученных, параллелизма точно не будет. А если не блокирует, а обрабатывает их в отдельном потоке - то уже можно говорить о параллелизме в той или иной степени. Ну а дальше есть всякие варианты того, как это реализовать и какие есть ограничения.
Только в посте про это ни слова, автор поста целиком полагается на библиотеку, которую использует.
ну я ИлонМаск который через бота веду свой блог. В Боте можно лайкать , из него репостить , голосовашки разные, добавлять комменты.
Аудитория 150 млн человек. После поста в первые 20 секунд больше лайков чем у Леди Гаги около ~270k + прибавляем все остальные выше перечисленные действия.
Что я должен делать? Твой код подойдет для меня (ИлонМаска)?
Если как ты пишешь ""вопрос-ответ", то что миллионы пользователей будут жать на кнопку , ничего не будет происходить т.к. они все встанут последовательно в очередь на ответ?
я не специалист в этом, только сделаю предположение, что это задача сервера Telegram, он создаёт инстанс на каждый запрос - то есть копию обработчика и каждый запрос обрабатывается с разными ID Threads. Если API изначально задумывался как то, что будет работать на стороне владельца бота, то у меня для вас печальные новости, если вы захотите чтобы ваш бот работал с миллионами одновременных запросов, то у вас как минимум три проблемы которые нужно будет решить - провайдер, железо, а уже потом софт. Без первых двух абсолютно не важно насколько правильно и красиво у вас будет написан бот - он все равно не сможет обрабатывать все запросы (точнее, он будет обрабатывать только то, что будет успевать провайдер и ваше железо)
Если API изначально задумывался как то, что будет работать на стороне владельца бота
Какой API?
Очевидно, что код бота выполняется на той стороне, где бот развернут.
если вы захотите чтобы ваш бот работал с миллионами одновременных запросов, то у вас как минимум три проблемы которые нужно будет решить - провайдер, железо, а уже потом софт.
Как раз провайдер и "железо" в наш век облачной инфраструктуры - не проблема. Проблема - написать софт так, чтобы он это все эффективно использовал.
Как раз провайдер и "железо" в наш век облачной инфраструктуры - не проблема
Это не вопрос конечной реализации мощностей, на вашей площадке или на чужой, это вопрос финансов. На Марс слетать тоже вроде можно, но что-то очереди из обывателей пока нет.
это вопрос финансов
Предположительно, если мы пишем на аудиторию в 150 млн. человек, то финансы на мощности есть. Что возвращает нас к вопросу "как написать код, чтобы он справлялся".
Предположительно, если мы пишем на аудиторию в 150 млн. человек
вы уверены? мне кажется тут код для домашнего знакомства с ботами в ТГ.
"как написать код, чтобы он справлялся"
и вы непременно критерием качества статьи у человека написавшего в обучающем newbie формате хотите заполучить код со всеми фишками и плюшками? ну это странный подход. возможно в 9-ой статье он это и сделает.
вы уверены?
Я уверен в том, что если мы пишем на аудиторию в 150 млн. человек, то надо исходить из того, что финансы есть.
мне кажется тут код для домашнего знакомства с ботами в ТГ.
Так про это выше и спрашивали: если у меня такая аудитория, тогда мне подойдет этот код? Ответ "нет, не подойдет" (который ниже дал автор) - тоже ответ, вполне честный.
и вы непременно критерием качества статьи у человека написавшего в обучающем newbie формате хотите заполучить код со всеми фишками и плюшками?
Нет. Для меня одним из критериев качества будет то, что ограничения кода, приведенного для обучения, будут упомянуты (а принятые решения - объяснены). А если у меня создается ощущение, что автор обучающей статьи сам не знает какие-то вещи, которые в статье использует, доверия такое статья у меня будет меньше.
у меня больше вопросов к тому зачем вы вообще зашли в эту статью, она не для вас 100%, она для меня и полезна для меня. вы же написали 1 статью 9 лет назад (видимо как условие для хабра) но настрочили 24К комментариев. Не хотите писать совсем. Об этом я сказал в самом начале, но претензии к тем кто пишет у вас всегда имеются. Почтупите правильно, напишите статью про бота в ТГ ПРАВИЛЬНО, со всеми плюшками, потоками и блэкджеком. Иначе пока от вас польза нулевая.
у меня больше вопросов к тому зачем вы вообще зашли в эту статью
Чтобы люди, которые ее прочитают, не совершали те же ошибки, которые совершает автор.
я уже сказал - напишите один раз правильную статью, а то весь мир учится на статьях начинающих которые не боятся писать, пока вы там сидите на диване с умным видом.
весь мир учится на статьях начинающих которые не боятся писать
У вас, видимо, другой "весь мир". Вокруг меня полно людей, которые учатся на документации, книжках и статьях, которые пишут профессионалы, а поверх щедро заливают это чтением исходников и отладкой.
а я где-то написал что так не бывает. люди разные и очень.
я например совсем не понимаю чужой код, я могу его только скопировать или написать свой. (для особо одаренных в этом месте напишу, что нет, я не считаю что все такие, но я могу судить по разным сайтам где тусуются новички и у них схожие проблемы, поэтому конкуренция на топовых позициях разработчиков не 1 место для миллионов кандидатов, а куда попроще)
Не хотите писать совсем.
Но вообще да, вы правы, не хочу. У меня нет иллюзий, что мне есть, что рассказать в формате статьи. Все, что я знаю - это тривиальный опыт, почерпнутый из большого количества разрозненных источников и не меньшего количества дебага очень специфических случаев, актуальных для меня, но не актуальных для широкой публики. Ну вот знаю я, допустим, как запустить ASP.NET Core внутри vanilla ASP.NET внутри IIS...и что? Кому, кроме меня (и моего работодателя) это надо? И это еще не считая количества согласований на NDA, которые придется пройти.
Этот проект не рассчитывался как что-то большое, для большой аудитории. В начале статьи сказано, что в этой статье я даю необходимую базу, чтобы вы писали своих ботов, используя эту базу. Поэтому здесь идет акцент больше на теоретических знаний, что, куда и почему.
Поэтому здесь идет акцент больше на теоретических знаний, что, куда и почему.
"Как обрабатывать многопоточность" - это как раз вполне себе теоретическая база.
"Как обрабатывать многопоточность" - это как раз вполне себе теоретическая база
не соглашусь, это вообще другой уровень разработки.
"Другой" по сравнению с чем? Базовая конкурентность и асинхрония в .net сейчас... базовая. Никак не выше миддла. Более того, даже джуниорам по ней придется ходить неизбежно, главное, с тропинки не сходить.
это всегда тема номер Х, но точно не тема номер 1.
В современном .net если захотеть просто сделать HTTP-запрос, это станет темой номер 1. Собственно, весь основной API в библиотеке, которую использует автор поста, асинхронный, так что если не уметь работать с task-based asynchrony, можно влететь в проблемы (как, например, с CancellationToken).
Вы в учебнике по бейсику предлагаете начать не с PRINT "HELLO WORLD!", а с A$=USR$("j2k_3ijsxcP{Phfewuhoi") что не имеет смысла по понятным причинам. Так и с этим ботом, пишется базовое, вводная тема, показывается как всё запустить, а потом рассказываются оптимизации, твики и прочее. Например при изучении сортировок всегда идут от наивных методов. Никто не учит графы на первом занятии.
В данном коде все будет работать последовательно, параллельной работы программы нет. Чтобы код работал в параллельном режиме, нужно использовать треды (thread) или таски (task), я предпочитаю таски, ставлю Task.Run в UpdateHandler и все работает прекрасно.
Добрый день! Разобрались в итоге как быть с параллельной обработкой? Ведь, если просто воткнуть Task.Run, есть вероятность, что ответы начнут приходить юзеру не в том порядке, если он пишет быстро, а действия в ответ на запрос занимают разное время. Может заводите очереди под юзеров на бэке?
Интересно было бы посмотреть как это вяжется с ИИ, а не хардкод «ответ-вопрос». Есть над чем подумать в продолжении данной темы. В целом есть немного замечаний по коду, так как чувствуется немного универских винформ, но для начала пойдет. Также вопрос насколько система будет работать с полным потоком пользователей? Были ли мысли об этом на этапе разработки?
В смысле вяжется с ИИ ? Немного не понял вопроса. Продолжение обязательно будет.
В целом есть немного замечаний по коду, так как чувствуется немного универских винформ, но для начала пойдет.
Честно говоря, в универе меня учили только C и после C++, C# я учу сам, используя разные ресурсы (книги, видеоуроки, статьи, интернет-материалы), поэтому я был бы очень рад получать критику моему коду, чтобы совершенствоваться!
Также вопрос насколько система будет работать с полным потоком пользователей? Были ли мысли об этом на этапе разработки?
Конкретно этот пример работает в последовательном режиме, параллельности тут нет, но ее легко добавить. В следующей статье обязательно рассмотрим этот пример. Насчет пользователей, за моей спиной уже несколько ботов и пока полеты отличные, пользователей не так много, где-то 500-1000 на бота и все отлично. Может, при увеличении пользователей где-то будут провалы, но пока все стабильно.
Привет всем как человеку который базово знает C Sharp и который до этого работал на Python со схожими библиотеками по Telegram ботам (тоже базово) хочу сказать что сам урок сделан довольно-таки неплохо лично я понял практически всё и хочу сказать что я был бы рад если выйдет продолжение особо не понимаю Почему так много людей так сильно придираются к этому уроку ведь, ну базово тут всё довольно-таки понятно А все ошибки - Это мелочи
Уже было много статей по написанию простейшего бота.
Где бы найти статью по грамотной архитектуре сложных ботов с магазинами, оплатой, авторизацией и прочим
Автору большое спасибо, дал вектор куда и как работать с библиотекой!!! Ты главное донес смысл работы с библиотекой!
PS А на умников не обращай внимания, всегда найдется кто захочет выделиться из толпы! А нормальный программер, молча сам напишет свой код и просто скажет спасибо!
Как написать Telegram бота на C#?