Видео про хост действительно нужно, потому что даже написание обычно тг бота можно сделать с ним и уже получить с этого что-то. Я про хост мало очень что знаю, но очень интересно как он работает. Всем мира
Про потоки в самом начале - херню сказал. Есть класс Thread - и он используется когда поток СОЗДАЁТСЯ и так ДЕЛАЮТ для создания независимого потока... Это важно, если у нас задача ДОЛГАЯ и комплексная. И есть класс ThreadPool - в который можно поместить функцию/делегат для выполнения в уже ПОДГОТОВЛЕННОМ и созданном потоке, которых там создано предварительно несколько, но они (каждый) делают "ничего" по умолчанию, но подставленная функция/делегат это "ничего" подменяет на себя и выполняется в этом подготовленном потоке, что экономит ресурсы, по сравнению со Thread. Вообще он предназначен для коротких и небольших вызовов - идеально подходящих под Task и прочие весёлости. Поток из ThreadPool можно сделать взаправдашним, всамделишным и долгим - применив опцию LongRunning. Важно помнить, что Task и async - НЕ ОБЯЗАТЕЛЬНО приведут к использованию ThreadPool и отдельных потоков.... Если задача быстрая и процесс "ждёт" то задачи Task - могут быть выполнены в основном потоке. P.S. Слишком много сумбура - вплоть до того, что показал аж два раза одно и то же. P.P.S. На примерно 38:45 - ты сказал, что "так мы асинхронности не добъёмся" - выполняя таск и доходя до Task.Result - так это и ЕСТЬ асинхронность. В этом её смысл: ты в отдельном Task.Run - ЗАПУСТИЛ операцию, но не стал ждать окончания, а по основному потоку - ПОШЁЛ ДАЛЬШЕ и дошёл до момента когда тебе НУЖНЫ ДАННЫЕ из операции, которая ещё работает... Вот тогда процесс и должен остановиться - подождать эти данные, ибо их ещё нет. Это и есть асинхронность, которая работает. ДО того момента, как тебе начинают быть необходимы ДАННЫЕ из ДРУГИХ потоков ты идёшь независимо, но как только одному потоку становятся нужны данные - в этом случае тебе и надо ждать и как ты опишешь это "ожидание" - через .Result, Wait, WaitAll, ContinueWith. И фактически в какой-то момент ты всё равно рано или поздно будешь дожидаться каких то данных и async/await - это как бы синтаксический сахар, для оборачивания в ContiinueWith всё что включает ИСПОЛЬЗУЕМЫЕ данные и всё что после них, что не такое уж принципиальное отличие... от ожидания в нужном месте.
Как я понимаю, асинхронность != многопоточности. Дело тут в том, что идея асинхронности сама по себе состоит в не блокировании основного потока программы, а НЕ создания ОТДЕЛЬНОГО потока для параллельного выполнения. По сути, такие операции называют I/O операции, то есть ввода-вывода, они не нагружают ЦП, поэтому выполняется асинхронно, то есть в одном и том же потоке. Почему в одном потоке? Хотя я знаю, что в консольном приложении там выделяются потоки из пула, вроде, но например, в каком-нибудь Winforms или WPF, или на игровом движке Unity все асинхронные операции обрабатываются в одном потоке. Но вот где обрабатываются сами операции я до конца не понял, как я читал, они передаются в очередь операционной системы, которая на уровне железа обрабатывает, например, чтение файла, так как это операции не нагружает ЦП, ибо выполняется на уровне вашего диска, то она называется I/O операция, операционная система получает ответ от диска, что он закончил чтение и у него есть результат, потом операционная система уведомляет, вроде бы, планировщик задач, который говорит нам, что можно вернутся в этот метод, так как есть результат и продолжить его выполнение. Поправь меня, если я что-то не то говорю. А вот параллельность это другое. Там мы выделяем независимый поток, которые доступны на уровне процессора, чтобы выполнить код параллельно, если у нас операции по типу CPU bounds , то есть та, которая нагружает наш ЦП, например, сложные расчеты, которые должны выполняться именно параллельно, а не асинхронно, ибо у нас будет лагать программа от такой нагрузки. Но как я выше говорил, что асинхронность это не многопоточность, но это не везде так, как я понял, консоль это исключение, но какие нибудь Winforms или Unity, где есть главный поток отрисовки или рендера, то там асинхронный операции выполняются все в главном потоке, но просто его не блокируя, так как они являются АСИНХРОННЫМИ. Фух, я так устал это писать, если есть дополнения, то прошу ответить 😅
@@Tera-h7e Совершенно правильно, что асинхронность НЕ РАВНО многопоточности, но вот тут как раз и заключается нюанс, что варианты: 1. Гарантированно сами создаём поток и упихиваем функционал туда, в идеале - НЕ стопим его до конца и НЕ прерываем - функция должна доработать до конца, иначе нафиг мы его создавали то? Это гарантированная многопоточность или скорее РАЗНОпоточность. 2. Работаем и, когда надо, гарантированно создаём или используем ПРЕсозданный поток, для организации вычислений - и тут у нас разница как раз в скорости созданеия и количестве затрачиваемых ресурсов. И тут СИСТЕМА решает - это будет новый или пресозданный поток. Можно подрегулировать, но не более. 3. Работаем и, когда надо - НЕ создаём поток и НЕ используемый готовый, потому что один фиг - текущий процесс ничем не занят - почему бы не продолжить выполнение - условно - подпотоковых вычислений - в нём. Он один хрен ничего не делает. И тут тоже СИСТЕМА решает. И вот вот СИСТЕМА РЕШАЕТ - выделять поток или выполнять в том же потоке - обернули в async/await и назвали асинхронностью. Там под всей этой обёрткой - могут быть важнейшие решения о том - как выделять поток или не выделять, но это от нас сокрыто. И в какой-то мере - хорошо, потому что и так всё запутано. Чистая параллельность - это фактически использование Thread, когда создаётся отдельный поток и он весь уходит ядру процессора - физическому. У нас же сейчас многоядерные процы, которые мало того -п поддерживают по 2 потока каждое ядро (обычно). Т.е. мы выделяем ресурсы и оно отдаётся из Ядра 1, Поток 1 в Ядро 1, поток 2, а когда закончится - Ядру 1, Поток 1 - может прийти результат (если мы это написали и синхронизировали), а может и не прийти. В случае же асинхронности работа этого ThreadPool, в котором крутятся "пустые потоки", готовые к исполнению - от нас скрыты. Я не находил инфы как ИМЕННО определяется выделение отдельного потока или выполнение в текущем. Есть факт что там просто крутятся подготовленные потоки, которым можно вклинить таск "на выполнение". Выполнил - молодец, не выполнил - увы. А вот async/await это просто две команды, одна из которых говорит, что вот там внутри какая-то неясность со скоростью выполнения - может быть долго (async), а вторая командует - надо подождать, пока не вернётся то, что мы запихнули в этот псевдопоток (давай это так назовём) (await). Мало того - эти async await (кстати как и lock и Monitor.Enter/Monitor.Exit) работают на уровне ПРИЛОЖЕНИЯ. То бишь если запустить ДВА ОДИНАКОВЫХ приложения, которые лезут в ОДИН и ТОТ же РЕСУРС - I/O - используются только каждый в своём приложении и всё может быть плохо с точки зрения драки за ресурс. Ну то бишь скорее всего всё будет относительно безопасно, но ускорения - не будет, потому что реальным головкам диска прийдётся прыгать и делать это быстро. И в этом случае - операции с использованием дискового I/O логичнее делать на Thread, потому что ИХ мы можем конфигурировать Семафорами, которые - на минуточку - СИСТЕМНЫЕ объекты. То бишь зарегистрированный Семафор мы зрим на уровне Операционной Системы, потому что это её объект, и разные приложения могут быть разрулены семафором. P.S. Насчёт Unity - не знаю, а в WinForms вполне можно писать асинхронно вообще без каких то проблем (потому я и назвал async/await - синтаксическим сахаром), но до кучи - МНОГОПОТОЧНО или РАЗНОПОТОЧНО - тоже без каких либо проблем. Нужно помнить лишь, что вызывать операции, работающие с GUI можно выполнять из базового потока, что приводит нас к использованиям Invoke, для например отсчёта прогресса, работающего в другом потоке - то бишь прогресс поток, чтобы обновить Progress bar GUI просто вызывает Progressbar.Step(1) не напрямую, а через - вызов функции, в которой мы делаем if(InvokeRequired) { Invoke(1) } else { Progressbar.Step(1); }
@@vasilyh4588 Ваш текст содержит множество интересных идей, но он также довольно длинный и немного запутанный. Давайте разберем его по частям и уточним некоторые моменты. Асинхронность и многопоточность Асинхронность и многопоточность - это разные концепции, хотя иногда они могут пересекаться. Асинхронность - это способ организации кода, который позволяет программе продолжать выполнение других задач, пока ожидается завершение длительной операции (например, I/O-операции). В этом случае программа не блокируется, и управление возвращается в основной поток выполнения. Многопоточность - это способ организации кода, при котором несколько потоков выполнения работают параллельно. Каждый поток может выполнять свою задачу независимо от других. Ваши варианты Гарантированно создаём поток: Это действительно многопоточность. Вы создаете новый поток и передаете ему задачу. Этот поток будет выполняться независимо от основного потока. Используем пул потоков: Это также многопоточность, но с использованием пула потоков (ThreadPool). Система сама решает, какой поток использовать для выполнения задачи. Это более эффективно, чем создание нового потока для каждой задачи, так как пул потоков уже содержит готовые к использованию потоки. Выполнение в текущем потоке: Это скорее асинхронность, чем многопоточность. Если текущий поток не занят, то система может выполнить задачу в этом же потоке, не создавая новый. Это экономит ресурсы, но не гарантирует параллельного выполнения. Async/Await Async/Await - это синтаксический сахар в языках программирования (например, C#), который упрощает написание асинхронного кода. Когда вы используете await, система может решить, выполнить ли задачу в текущем потоке или передать её в пул потоков. Это зависит от реализации и контекста выполнения. Параллельность и Thread Параллельность - это действительно использование нескольких потоков для выполнения задач одновременно. Каждый поток может быть назначен на отдельное ядро процессора, что позволяет использовать все доступные ресурсы процессора. I/O и многопоточность Вы правы, что для операций с дисковым I/O (например, чтение/запись файлов) может быть более эффективным использование многопоточности, так как эти операции могут блокировать поток на длительное время. Однако, в современных операционных системах и библиотеках, таких как .NET, асинхронные операции I/O (например, File.ReadAllTextAsync) могут быть очень эффективными, так как они используют неблокирующие системные вызовы. Синхронизация и семафоры Семафоры - это системные объекты, которые позволяют синхронизировать доступ к ресурсам между разными процессами и потоками. Они действительно могут быть полезны для управления доступом к общим ресурсам, таким как файлы или сетевые соединения. Unity и WinForms Unity: В Unity асинхронность также может использоваться, но она может быть немного сложнее из-за особенностей работы с игровым циклом. WinForms: В WinForms асинхронность работает без проблем, но важно помнить, что операции с GUI должны выполняться в основном потоке. Для этого используются методы Invoke или BeginInvoke. Заключение Ваш текст содержит много правильных идей, но он может быть немного запутанным для тех, кто не знаком с этими концепциями. Асинхронность и многопоточность - это мощные инструменты, но они требуют понимания их особенностей и правильного использования в зависимости от задачи.
@@Norsik_Official Спасибо. Реально. не подумал, что кому то может быть непонятно из за "специфики новичка". Я полностью согласен с вашими описаниями. Вы абсолютно правы и касательно многопоточности и асинхронности как это воспринимается СЕЙЧАС с точки зрения ПРИНЯТОЙ ТЕРМИНОЛОГИИ. Есть момент, который я хотел бы подчеркнуть: Формально в Асинхроне - мы делаем что-то НЕ БЛОКИРУЯ поток, потом возвращаемся в указанной точке для ожидания данных или в Многопотоке мы запускаем действия в отдельно потоке точно также НЕ БЛОКИРУЯ основной поток, а потом в указанной точке ожидаем данные если второй поток их возвращает - то бишь формально это одно и то же. Они в данном контексте работают одинаково: и там и там не блокируют осонову и там и там ждут окончания в указанном месте. Ключевое отличие - для Многопотока создание и "указанное место" надо самому ручками писать. Т.е. СУТЬ - одна и та же. Поэтому я бы сказал, что при формально ОДИНАКОВОМ поведение: Асинхрон - просто легче для восприятия и конфигурации Многопоток - потяжельше в плане настройки. Поэтому это выделили в разные ТЕРМИНОЛОГИЧЕСКИЕ понятия для разделения, не отменяя самой сути действий - не блокировать основной поток в процессе выполнения сторонних задач.
привет. очень скептически отношусь к твоим видео. это видео еще не досмотрел, но тут очень заходит подача. думаю, для человека, который только входит в asp net, это прям кладезь полезной информации! спасибо! буду рекомендовать ребятам которые не понимают на пальцах, как работает асинхронность.
Редко пишу комментарии, но сейчас не сдержался... Спасибо большое за такую подробную информацию, много нового узнал, несмотря на то что изучал эту тему ранее. Действительно классный видеоролик, попутно конспектировал себе информацию которую впервые слышу, сейчас приступлю к дальнейшему изучению.
Я изучаю программирование довольно давно и асинхронность в свое время была довольно сложной темой. На ютубе как правило не попадались такие подробные обьяснения темы и приходилось собирать общее понимание по крупицам. У тебя удалось составить хорошее и понятное обьяснение. Молодец)
Очень крутой видос! Спасибо за твой контент, помогает разобраться в таких казалось бы простых вещах, но в них просто миллион нюансов. Хотел бы увидеть что то про локи и монитор. А также примитивы синхронизации - площадка по данным вопросам сильно пустует, видосы 3-5 летней давности.
Привет. Заметил уже не в первом ролике проблему. У тебя темп повествования ускоряется и становится рваным в процессе объяснения. Это ведёт к потере фокуса внимания зрителем и неусвоением материала. Обрати внимание, какой темп в блоке со старыми тасками, и например в блоке с "теорией" в начале. Ощущение, что вначале ты хочешь объяснить, а потом поскорее отстреляться от какой-то проходной темы :) Как избежать, особенно на длинных роликах. Да и не только. Записывай частями. Отработал сценарий на один блок. Посмотрел, как вышло на сыром материале. Если ок, то перекур, и только потом отработать следующий блок. Ровно в таком же темпе. Затем уже на монтаже блоки склеить, разделив отбивками. Раньше в отбивки можно было рекламу вкорячить, и это никого не бесило. Щас реклама вышла из чата, поэтому отбивки можно просто как более длинные паузы делать. Или интеграции вставлять, которые все спокойно перематывают😂 поэтому интеграции тоже удобно делать кратными 10 сек + несколько секунд, т.к. двойной тап на телефоне скипает 10 сек ролика. С опытом можно будет легко и длинные ролики за один присест писать, но это надо реально дохера практиковаться. К слову, все сериалы, например, делаются по такому же принципу. Есть примерно одинаковые блоки, разделённые отбивками. + Реклама. Как итог - потери внимания у зрителя не происходит. Они идут на кухню за пивом во время рекламы,и успевают отдохнуть 😂 Можешь рассматривать эти блоки, как классы. Ты же не пишешь один класс нормально, а второй кое как. Всегда +- одинаково. А тут получается, одно сделано хорошо. А второе - как попало. Это самая примитивная аналогия. И да, вебка занимает реально много места. Условный "круг" в углу по маске, вместо прямоугольника, содержания вебки особо не ущемляет, но позволяет получить больше места с текстом на экране. А когда что-то важное поясняется, её вообще можно убрать. Это сработает, как пауза в тексте - фокус внимания. Т.к. пропадает статика в картинке. Материал полезный, особенно для начинающих. Хотелось бы, чтобы и качество подачи не отставало :)
@@KirillSachkov я бы не сказал, что это прям критика. Скорее, конструктивный комментарий по форме. Сам наступал на те же грабли, да и многие наступают :) Тут лишь вопрос желания работать над этим. Кстати, как следствие работы над темпом будет сайд эффект. Слова паразиты начнут постепенно уходить. Все эти "нуууу", заикания и прочее. Всё, что присуще "живой начитке", когда ты не с суфлёра читаешь по готовому тексту сценария, а с ходу фигачишь :) Я думаю, ты и сам понимаешь эту проблему. Для референса можно просто взять и посчитать, сколько проблем с паразитами и нечёткими формулировками есть сейчас в ролике. И сколько их будет по прошествии времени, как усиленно начнёшь работать над темпом. Результат удивит :) Формулировать мысль на лету, особенно когда объясняешь что-то - достаточно сложная задача. А чёткость формулировок напрямую влияет на восприятие и усвоение. Ещё раз спасибо за поднимаемые темы, позволяет освежить в голове или сходить почитать что-то и разобраться поглубже. Ну и успехов в творчестве :)
Спасибо за видос! Но после просмотра не очень понятно, почему синхронный код называют именно синхронным, если же по факту он выполняет кодовые блоки последовательно, а не синхронно (паралельно в одно и то же время). С аснихронным таже история. Как будто названия напутали
привет, спасибо за полезный ролик! немного не понял разницы между thread.sleep и task.delay().wait(). не понимаю почему в первом случае сообщения быстро выводятся в консоль и секундная пауза никак не заметна, а во втором секундная пауза отчетливо заметна? буду благодарен,если объясните)))
Не могу понять почему api запросы последовательно выполняются, запускаю в 4 потока, все идет одновременно, доходит до самого запроса и начинается последовательно. Хотя вроде везде поставил асинхронные версии методов
Хорошее видео, правда хотелось бы увидеть взаимодействие с асинхронным кодом на полу реальном примере :). Например с разбором "типичных" тупиковых ситуаций (я даже не знаю, что привести в пример :) опыта нет)
На 25 минуте автор ошибается. Фраза "мы здесь вырубаем поток на секунду и моментально переходим к следующией строке" - ложь. Thread.Sleep - блокирующая операция, и между двумя выводами будет задержка. Не совсем понятно, как считает автор - если мы "вырубаем поток" - то какой поток выполняет "переходим на следующую строку". Автор вводит в заблуждение людей, которые не разбираются в этом, что делает такие видео вредными
не судите так строго, человеку надо максимально коротко и емко объяснить сложную тему. он не первый, который ошибся в видео на ютубе )) Мне кажется, что видео написано без сценария, и в процессе рассказа он второпях перепутал работу Thread.Sleep с Task.Dekay, вызванную без await. А насчет "вредности", если слушать автора и не повторять код, то все равно ничего путевого в плане знаний не получится, Зато вот если сам повторил и обнаружил ошибку - на всю жизнь запомнишь, как оно на самом деле работает. Как и вы, увидел ошибку, но на всякий случай потратил пару минут и проверил, мало ли туплю )) Полезная привычка все проверять, как мне кажется
Было бы прикольно если бы научил деплоить на своем канале. Ведь благодаря тебе я нормально могу использовать fullstack разработку. (до этого все думал asp core mvc использовать). Поэтому жду) Также отдельно видео про докер и docker-compose
Переходи в мой телеграм канал - t.me/sachkov_blog
Все ждал когда ты скажешь про ConfigureAwait - это важнейший метод, но увы…
Видео про хост действительно нужно, потому что даже написание обычно тг бота можно сделать с ним и уже получить с этого что-то. Я про хост мало очень что знаю, но очень интересно как он работает. Всем мира
Значит будет
Новое видео ❤ не устану повторять: отличный контент, без воды и современный. Спасибо!
Спасибо
Про потоки в самом начале - херню сказал.
Есть класс Thread - и он используется когда поток СОЗДАЁТСЯ и так ДЕЛАЮТ для создания независимого потока... Это важно, если у нас задача ДОЛГАЯ и комплексная.
И есть класс ThreadPool - в который можно поместить функцию/делегат для выполнения в уже ПОДГОТОВЛЕННОМ и созданном потоке, которых там создано предварительно несколько, но они (каждый) делают "ничего" по умолчанию, но подставленная функция/делегат это "ничего" подменяет на себя и выполняется в этом подготовленном потоке, что экономит ресурсы, по сравнению со Thread. Вообще он предназначен для коротких и небольших вызовов - идеально подходящих под Task и прочие весёлости.
Поток из ThreadPool можно сделать взаправдашним, всамделишным и долгим - применив опцию LongRunning.
Важно помнить, что Task и async - НЕ ОБЯЗАТЕЛЬНО приведут к использованию ThreadPool и отдельных потоков.... Если задача быстрая и процесс "ждёт" то задачи Task - могут быть выполнены в основном потоке.
P.S. Слишком много сумбура - вплоть до того, что показал аж два раза одно и то же.
P.P.S. На примерно 38:45 - ты сказал, что "так мы асинхронности не добъёмся" - выполняя таск и доходя до Task.Result - так это и ЕСТЬ асинхронность. В этом её смысл: ты в отдельном Task.Run - ЗАПУСТИЛ операцию, но не стал ждать окончания, а по основному потоку - ПОШЁЛ ДАЛЬШЕ и дошёл до момента когда тебе НУЖНЫ ДАННЫЕ из операции, которая ещё работает... Вот тогда процесс и должен остановиться - подождать эти данные, ибо их ещё нет. Это и есть асинхронность, которая работает. ДО того момента, как тебе начинают быть необходимы ДАННЫЕ из ДРУГИХ потоков ты идёшь независимо, но как только одному потоку становятся нужны данные - в этом случае тебе и надо ждать и как ты опишешь это "ожидание" - через .Result, Wait, WaitAll, ContinueWith.
И фактически в какой-то момент ты всё равно рано или поздно будешь дожидаться каких то данных и async/await - это как бы синтаксический сахар, для оборачивания в ContiinueWith всё что включает ИСПОЛЬЗУЕМЫЕ данные и всё что после них, что не такое уж принципиальное отличие... от ожидания в нужном месте.
Как я понимаю, асинхронность != многопоточности. Дело тут в том, что идея асинхронности сама по себе состоит в не блокировании основного потока программы, а НЕ создания ОТДЕЛЬНОГО потока для параллельного выполнения. По сути, такие операции называют I/O операции, то есть ввода-вывода, они не нагружают ЦП, поэтому выполняется асинхронно, то есть в одном и том же потоке. Почему в одном потоке? Хотя я знаю, что в консольном приложении там выделяются потоки из пула, вроде, но например, в каком-нибудь Winforms или WPF, или на игровом движке Unity все асинхронные операции обрабатываются в одном потоке. Но вот где обрабатываются сами операции я до конца не понял, как я читал, они передаются в очередь операционной системы, которая на уровне железа обрабатывает, например, чтение файла, так как это операции не нагружает ЦП, ибо выполняется на уровне вашего диска, то она называется I/O операция, операционная система получает ответ от диска, что он закончил чтение и у него есть результат, потом операционная система уведомляет, вроде бы, планировщик задач, который говорит нам, что можно вернутся в этот метод, так как есть результат и продолжить его выполнение. Поправь меня, если я что-то не то говорю. А вот параллельность это другое. Там мы выделяем независимый поток, которые доступны на уровне процессора, чтобы выполнить код параллельно, если у нас операции по типу CPU bounds , то есть та, которая нагружает наш ЦП, например, сложные расчеты, которые должны выполняться именно параллельно, а не асинхронно, ибо у нас будет лагать программа от такой нагрузки. Но как я выше говорил, что асинхронность это не многопоточность, но это не везде так, как я понял, консоль это исключение, но какие нибудь Winforms или Unity, где есть главный поток отрисовки или рендера, то там асинхронный операции выполняются все в главном потоке, но просто его не блокируя, так как они являются АСИНХРОННЫМИ. Фух, я так устал это писать, если есть дополнения, то прошу ответить 😅
@@Tera-h7e Совершенно правильно, что асинхронность НЕ РАВНО многопоточности, но вот тут как раз и заключается нюанс, что варианты:
1. Гарантированно сами создаём поток и упихиваем функционал туда, в идеале - НЕ стопим его до конца и НЕ прерываем - функция должна доработать до конца, иначе нафиг мы его создавали то? Это гарантированная многопоточность или скорее РАЗНОпоточность.
2. Работаем и, когда надо, гарантированно создаём или используем ПРЕсозданный поток, для организации вычислений - и тут у нас разница как раз в скорости созданеия и количестве затрачиваемых ресурсов. И тут СИСТЕМА решает - это будет новый или пресозданный поток. Можно подрегулировать, но не более.
3. Работаем и, когда надо - НЕ создаём поток и НЕ используемый готовый, потому что один фиг - текущий процесс ничем не занят - почему бы не продолжить выполнение - условно - подпотоковых вычислений - в нём. Он один хрен ничего не делает. И тут тоже СИСТЕМА решает.
И вот вот СИСТЕМА РЕШАЕТ - выделять поток или выполнять в том же потоке - обернули в async/await и назвали асинхронностью. Там под всей этой обёрткой - могут быть важнейшие решения о том - как выделять поток или не выделять, но это от нас сокрыто. И в какой-то мере - хорошо, потому что и так всё запутано.
Чистая параллельность - это фактически использование Thread, когда создаётся отдельный поток и он весь уходит ядру процессора - физическому. У нас же сейчас многоядерные процы, которые мало того -п поддерживают по 2 потока каждое ядро (обычно). Т.е. мы выделяем ресурсы и оно отдаётся из Ядра 1, Поток 1 в Ядро 1, поток 2, а когда закончится - Ядру 1, Поток 1 - может прийти результат (если мы это написали и синхронизировали), а может и не прийти.
В случае же асинхронности работа этого ThreadPool, в котором крутятся "пустые потоки", готовые к исполнению - от нас скрыты. Я не находил инфы как ИМЕННО определяется выделение отдельного потока или выполнение в текущем. Есть факт что там просто крутятся подготовленные потоки, которым можно вклинить таск "на выполнение". Выполнил - молодец, не выполнил - увы. А вот async/await это просто две команды, одна из которых говорит, что вот там внутри какая-то неясность со скоростью выполнения - может быть долго (async), а вторая командует - надо подождать, пока не вернётся то, что мы запихнули в этот псевдопоток (давай это так назовём) (await).
Мало того - эти async await (кстати как и lock и Monitor.Enter/Monitor.Exit) работают на уровне ПРИЛОЖЕНИЯ. То бишь если запустить ДВА ОДИНАКОВЫХ приложения, которые лезут в ОДИН и ТОТ же РЕСУРС - I/O - используются только каждый в своём приложении и всё может быть плохо с точки зрения драки за ресурс. Ну то бишь скорее всего всё будет относительно безопасно, но ускорения - не будет, потому что реальным головкам диска прийдётся прыгать и делать это быстро.
И в этом случае - операции с использованием дискового I/O логичнее делать на Thread, потому что ИХ мы можем конфигурировать Семафорами, которые - на минуточку - СИСТЕМНЫЕ объекты. То бишь зарегистрированный Семафор мы зрим на уровне Операционной Системы, потому что это её объект, и разные приложения могут быть разрулены семафором.
P.S. Насчёт Unity - не знаю, а в WinForms вполне можно писать асинхронно вообще без каких то проблем (потому я и назвал async/await - синтаксическим сахаром), но до кучи - МНОГОПОТОЧНО или РАЗНОПОТОЧНО - тоже без каких либо проблем. Нужно помнить лишь, что вызывать операции, работающие с GUI можно выполнять из базового потока, что приводит нас к использованиям Invoke, для например отсчёта прогресса, работающего в другом потоке - то бишь прогресс поток, чтобы обновить Progress bar GUI просто вызывает Progressbar.Step(1) не напрямую, а через - вызов функции, в которой мы делаем if(InvokeRequired) { Invoke(1) } else { Progressbar.Step(1); }
@@vasilyh4588 Ваш текст содержит множество интересных идей, но он также довольно длинный и немного запутанный. Давайте разберем его по частям и уточним некоторые моменты.
Асинхронность и многопоточность
Асинхронность и многопоточность - это разные концепции, хотя иногда они могут пересекаться.
Асинхронность - это способ организации кода, который позволяет программе продолжать выполнение других задач, пока ожидается завершение длительной операции (например, I/O-операции). В этом случае программа не блокируется, и управление возвращается в основной поток выполнения.
Многопоточность - это способ организации кода, при котором несколько потоков выполнения работают параллельно. Каждый поток может выполнять свою задачу независимо от других.
Ваши варианты
Гарантированно создаём поток:
Это действительно многопоточность. Вы создаете новый поток и передаете ему задачу. Этот поток будет выполняться независимо от основного потока.
Используем пул потоков:
Это также многопоточность, но с использованием пула потоков (ThreadPool). Система сама решает, какой поток использовать для выполнения задачи. Это более эффективно, чем создание нового потока для каждой задачи, так как пул потоков уже содержит готовые к использованию потоки.
Выполнение в текущем потоке:
Это скорее асинхронность, чем многопоточность. Если текущий поток не занят, то система может выполнить задачу в этом же потоке, не создавая новый. Это экономит ресурсы, но не гарантирует параллельного выполнения.
Async/Await
Async/Await - это синтаксический сахар в языках программирования (например, C#), который упрощает написание асинхронного кода. Когда вы используете await, система может решить, выполнить ли задачу в текущем потоке или передать её в пул потоков. Это зависит от реализации и контекста выполнения.
Параллельность и Thread
Параллельность - это действительно использование нескольких потоков для выполнения задач одновременно. Каждый поток может быть назначен на отдельное ядро процессора, что позволяет использовать все доступные ресурсы процессора.
I/O и многопоточность
Вы правы, что для операций с дисковым I/O (например, чтение/запись файлов) может быть более эффективным использование многопоточности, так как эти операции могут блокировать поток на длительное время. Однако, в современных операционных системах и библиотеках, таких как .NET, асинхронные операции I/O (например, File.ReadAllTextAsync) могут быть очень эффективными, так как они используют неблокирующие системные вызовы.
Синхронизация и семафоры
Семафоры - это системные объекты, которые позволяют синхронизировать доступ к ресурсам между разными процессами и потоками. Они действительно могут быть полезны для управления доступом к общим ресурсам, таким как файлы или сетевые соединения.
Unity и WinForms
Unity: В Unity асинхронность также может использоваться, но она может быть немного сложнее из-за особенностей работы с игровым циклом.
WinForms: В WinForms асинхронность работает без проблем, но важно помнить, что операции с GUI должны выполняться в основном потоке. Для этого используются методы Invoke или BeginInvoke.
Заключение
Ваш текст содержит много правильных идей, но он может быть немного запутанным для тех, кто не знаком с этими концепциями. Асинхронность и многопоточность - это мощные инструменты, но они требуют понимания их особенностей и правильного использования в зависимости от задачи.
@@Norsik_Official Спасибо. Реально. не подумал, что кому то может быть непонятно из за "специфики новичка". Я полностью согласен с вашими описаниями.
Вы абсолютно правы и касательно многопоточности и асинхронности как это воспринимается СЕЙЧАС с точки зрения ПРИНЯТОЙ ТЕРМИНОЛОГИИ.
Есть момент, который я хотел бы подчеркнуть:
Формально в Асинхроне - мы делаем что-то НЕ БЛОКИРУЯ поток, потом возвращаемся в указанной точке для ожидания данных или в Многопотоке мы запускаем действия в отдельно потоке точно также НЕ БЛОКИРУЯ основной поток, а потом в указанной точке ожидаем данные если второй поток их возвращает - то бишь формально это одно и то же. Они в данном контексте работают одинаково: и там и там не блокируют осонову и там и там ждут окончания в указанном месте.
Ключевое отличие - для Многопотока создание и "указанное место" надо самому ручками писать.
Т.е. СУТЬ - одна и та же.
Поэтому я бы сказал, что при формально ОДИНАКОВОМ поведение:
Асинхрон - просто легче для восприятия и конфигурации
Многопоток - потяжельше в плане настройки.
Поэтому это выделили в разные ТЕРМИНОЛОГИЧЕСКИЕ понятия для разделения, не отменяя самой сути действий - не блокировать основной поток в процессе выполнения сторонних задач.
@@Norsik_Official абсолютно верно
Отличный контент, нужная инфа в сухом виде. Так держать, поддержку комментарием.)
Спасибо
хост🔝
Спасибо за видео!
На здоровье
Долго до конца не понимал эту тему. Спасибо за подробный рассказ с хорошими примерами
Очень крутое и понятное видео, большое спасибо за твой контент. Почти не осталось на ютубе таких подробных и понятных материалов.
Спасибо
привет. очень скептически отношусь к твоим видео. это видео еще не досмотрел, но тут очень заходит подача. думаю, для человека, который только входит в asp net, это прям кладезь полезной информации! спасибо! буду рекомендовать ребятам которые не понимают на пальцах, как работает асинхронность.
Почему скептически?)
Редко пишу комментарии, но сейчас не сдержался... Спасибо большое за такую подробную информацию, много нового узнал, несмотря на то что изучал эту тему ранее. Действительно классный видеоролик, попутно конспектировал себе информацию которую впервые слышу, сейчас приступлю к дальнейшему изучению.
Спасибо
Крутой туториал, спасибо, Кирилл
Спасибо
про CancellationToken бы еще сюда ко всему этому
Молодец, просто красава!
Желаю огромных успехов, и буду ждать по больше новых видосов
Я изучаю программирование довольно давно и асинхронность в свое время была довольно сложной темой. На ютубе как правило не попадались такие подробные обьяснения темы и приходилось собирать общее понимание по крупицам. У тебя удалось составить хорошее и понятное обьяснение. Молодец)
Спасибо!
Про host, kestrel тоже интересно будет услышать👍🏻
Будет
Урааа новый ролик)
Спасибо за видео! Как раз сейчас пытаюсь разобраться с асинхронностью
Спасибо. Обязательно гляну
Спасибо
Очень крутой видос! Спасибо за твой контент, помогает разобраться в таких казалось бы простых вещах, но в них просто миллион нюансов. Хотел бы увидеть что то про локи и монитор. А также примитивы синхронизации - площадка по данным вопросам сильно пустует, видосы 3-5 летней давности.
очень крутой контент, спасибо!
Спасибо
Видео про хост - необходимо!
Благодарю за данное видео. Учусь буквально по вашим видео урокам. Пересмотрел много разных авторов, но вас считаю одним из лучших по подаче материала.
Спасибо
Офигенная тема! Хорошо рассказано! Теперь про параллельность нужно и как его дебажить.
Полезно. Спасибо. ❤
Спасибо
Лайк не глядя. Вечером обязательно посмотрю. Спасибо
Спасибо
Круто. Спасибо
Спасибо
Обязательно ждём видео про хост!!!
огонь🔥👍
Привет. Заметил уже не в первом ролике проблему. У тебя темп повествования ускоряется и становится рваным в процессе объяснения. Это ведёт к потере фокуса внимания зрителем и неусвоением материала.
Обрати внимание, какой темп в блоке со старыми тасками, и например в блоке с "теорией" в начале. Ощущение, что вначале ты хочешь объяснить, а потом поскорее отстреляться от какой-то проходной темы :)
Как избежать, особенно на длинных роликах. Да и не только.
Записывай частями. Отработал сценарий на один блок. Посмотрел, как вышло на сыром материале. Если ок, то перекур, и только потом отработать следующий блок. Ровно в таком же темпе.
Затем уже на монтаже блоки склеить, разделив отбивками. Раньше в отбивки можно было рекламу вкорячить, и это никого не бесило. Щас реклама вышла из чата, поэтому отбивки можно просто как более длинные паузы делать. Или интеграции вставлять, которые все спокойно перематывают😂 поэтому интеграции тоже удобно делать кратными 10 сек + несколько секунд, т.к. двойной тап на телефоне скипает 10 сек ролика.
С опытом можно будет легко и длинные ролики за один присест писать, но это надо реально дохера практиковаться.
К слову, все сериалы, например, делаются по такому же принципу. Есть примерно одинаковые блоки, разделённые отбивками. + Реклама. Как итог - потери внимания у зрителя не происходит. Они идут на кухню за пивом во время рекламы,и успевают отдохнуть 😂
Можешь рассматривать эти блоки, как классы. Ты же не пишешь один класс нормально, а второй кое как. Всегда +- одинаково. А тут получается, одно сделано хорошо. А второе - как попало. Это самая примитивная аналогия.
И да, вебка занимает реально много места. Условный "круг" в углу по маске, вместо прямоугольника, содержания вебки особо не ущемляет, но позволяет получить больше места с текстом на экране. А когда что-то важное поясняется, её вообще можно убрать. Это сработает, как пауза в тексте - фокус внимания. Т.к. пропадает статика в картинке.
Материал полезный, особенно для начинающих. Хотелось бы, чтобы и качество подачи не отставало :)
Спасибо за обратную связь и здравую критику, буду работать над подачей
@@KirillSachkov я бы не сказал, что это прям критика. Скорее, конструктивный комментарий по форме. Сам наступал на те же грабли, да и многие наступают :) Тут лишь вопрос желания работать над этим.
Кстати, как следствие работы над темпом будет сайд эффект. Слова паразиты начнут постепенно уходить.
Все эти "нуууу", заикания и прочее. Всё, что присуще "живой начитке", когда ты не с суфлёра читаешь по готовому тексту сценария, а с ходу фигачишь :) Я думаю, ты и сам понимаешь эту проблему.
Для референса можно просто взять и посчитать, сколько проблем с паразитами и нечёткими формулировками есть сейчас в ролике. И сколько их будет по прошествии времени, как усиленно начнёшь работать над темпом. Результат удивит :)
Формулировать мысль на лету, особенно когда объясняешь что-то - достаточно сложная задача. А чёткость формулировок напрямую влияет на восприятие и усвоение.
Ещё раз спасибо за поднимаемые темы, позволяет освежить в голове или сходить почитать что-то и разобраться поглубже. Ну и успехов в творчестве :)
отлично!
Единственный видос который реально объясняет что такое асинхронность!
Очень хороший контент!
Хотелось бы увидеть,что-то по winapi
Да. Просим тебя. Расскажи пожалуйста про Host и kestrel
Привет, очень бросается в глаза: по конвенции в C# для констант используется PascalCase, а то, что у тебя, это что-то из C.
На 59:00 в WhenAny правильно параметры указаны? Там не tasks должно быть?
Сделай видео про Garbage Collector
Спасибо.
Спасибо
Спасибо за видос! Но после просмотра не очень понятно, почему синхронный код называют именно синхронным, если же по факту он выполняет кодовые блоки последовательно, а не синхронно (паралельно в одно и то же время). С аснихронным таже история. Как будто названия напутали
привет, заметил ты на mac работаешь, подскажи хорошо подходит он для .net разработки?
Да, все идеально работает
@@KirillSachkov можешь еще подсказать, я так понимаю это ide rider? тяжело было оформить подписку?
Это не лицензия
У тебя микро Fifine AM8?
Да
привет, спасибо за полезный ролик! немного не понял разницы между thread.sleep и task.delay().wait(). не понимаю почему в первом случае сообщения быстро выводятся в консоль и секундная пауза никак не заметна, а во втором секундная пауза отчетливо заметна? буду благодарен,если объясните)))
В этом моменте я ошибся и Thread.Sleep тоже блокирует поток и мы будем ждать, пока не пройдет заданное время
@@KirillSachkov спасибо!
Кирилл, как тебе на маке работать с .net?
Все отлично работает
Не могу понять почему api запросы последовательно выполняются, запускаю в 4 потока, все идет одновременно, доходит до самого запроса и начинается последовательно. Хотя вроде везде поставил асинхронные версии методов
Это не может быть правдой, потому что всё так просто (шутка). Спасибо за видео!
Хорошее видео, правда хотелось бы увидеть взаимодействие с асинхронным кодом на полу реальном примере :). Например с разбором "типичных" тупиковых ситуаций (я даже не знаю, что привести в пример :) опыта нет)
Такие ролики плодят конкуренцию на hh. Нужно их оставлять на курсах.
Сомневаюсь, что понимание асинхронности будет плодить конкуренцию)
😂
async/await довольно нагруженная структура, поэтому вставлять await без понимания и без надобности "просто так", лучше не надо.
жду новые ролики, ты лучший!
Спасибо
👍
На 25 минуте автор ошибается. Фраза "мы здесь вырубаем поток на секунду и моментально переходим к следующией строке" - ложь. Thread.Sleep - блокирующая операция, и между двумя выводами будет задержка. Не совсем понятно, как считает автор - если мы "вырубаем поток" - то какой поток выполняет "переходим на следующую строку".
Автор вводит в заблуждение людей, которые не разбираются в этом, что делает такие видео вредными
не судите так строго, человеку надо максимально коротко и емко объяснить сложную тему. он не первый, который ошибся в видео на ютубе )) Мне кажется, что видео написано без сценария, и в процессе рассказа он второпях перепутал работу Thread.Sleep с Task.Dekay, вызванную без await. А насчет "вредности", если слушать автора и не повторять код, то все равно ничего путевого в плане знаний не получится, Зато вот если сам повторил и обнаружил ошибку - на всю жизнь запомнишь, как оно на самом деле работает. Как и вы, увидел ошибку, но на всякий случай потратил пару минут и проверил, мало ли туплю )) Полезная привычка все проверять, как мне кажется
Ролик начинается с 38:30 не благодарите
А потом вы все дружно становитесь конкурентами друг другу на hh. 😂😂😂😂
Было бы прикольно если бы научил деплоить на своем канале. Ведь благодаря тебе я нормально могу использовать fullstack разработку. (до этого все думал asp core mvc использовать). Поэтому жду) Также отдельно видео про докер и docker-compose
Я бы про хост послушал
А я там был